Reputation: 35
I am having an architectural misunderstanding about execution order in MVC.
I am overriding initialization in my
public class HomeController: Controller {
protected override void Initialize(RequestContext requestContext)
{
var myVar = "AValue";
// basically run some internal security
initialization
}
Then in my javascript I am running a series of 10 Ajax calls with deferred promise().
Onload set 'em up and and run with the $when
Then <--not the keyword just different location
js:
this.BeginMyAjaxQuery = function() {
methodName: MyAjaxQuery
};
On an entirely different Controller that inherits my HomeController
public JsonResult MyAjaxQuery()
{
return Perform(() =>
{
return ThisQueryWithMyParameter(AValue);
});
}
Perform is a wrapper we have successfully used to create JsonResults
On to my misunderstanding of how MVC architecture behaves: When I load my URL, the AJAX runs all the way through on it's own thread Before I have completed my HomeController Initialization. Thus my variables are not set and when I get to the actual query execution I receive improper results... most of the time but not always. Which of course is even more annoying.
How is it that my ajax calls can bypass my Controller Initialization and move directly through to Controller methods?
To add to my confusion Adding my code to a constructor on my HomeController behaves in the same way. Erratic results.
Last bits, if it matters: Using Partial Views & KnockoutJS for front end delivery
Upvotes: 1
Views: 221
Reputation: 17658
staic
issueAs you described, you are using a static. While this helps accessing it from basically everywhere, but it has a another property: it is only initialized once, and the value you give it, is the value is has on all threads. (Well, actually this has a bit more nuances, like processor level caching, but I'll consider that out of scope for now.)
As for now: you should consider it as if there is only 1 Security User
object in memory. If you give it a value, it will be that value on all threads.
public class HomeController: Controller {
//note! static: the `new` is called only once!
static SecurityUser = new SecurityUser();
protected override void Initialize(RequestContext requestContext)
{
//so SecurityUser is not a fresh object.
//setting values will be shared between all
//threads (since there is only one SecurityUser object in memory
//shared across all threads
SecurityUser.Ip = "127.0.0.2";
}
As wikipedia states it:
In computing, a pipeline, also known as a data pipeline, is a set of data processing elements connected in series, where the output of one element is the input of the next one.
In general it describes the flow of data and the actions involved when processing a request.
There are articles about it everywhere, e.g: here and here.
The MSDN image explains it very well (and complete), I added it beneath.
If you look at the image you'll see AuthenticationFilters
, AuthorizationFilters
and ActionFilter
s. (See this link for more information about them.)
Their purpose, is to execute code, authentication etc. for some or all invoked ActionMethods. By using them, you can isolate your authentication behavior, (which is good OO practice) and keeps your code maintainable. The idea is, you'll only need to define your special security thing once.
You could use this to initialize a object with a certain interface, e.g.: ISecurity
with some properties like ip address, username, admin privileges etc. The object can be filled in an action filter, and can be resolved with a dependency resolver in every http call. Works like a charm.
image source: msdn
Upvotes: 1