Why are Controller Constructors fired before the Initialize method - asp.net-mvc

I have a base Controller ApplicationController that needs to grab the URL Host and do some processing before the child controllers are fired. Since controller constructors are fired before RequestContext is initialized I have to override Initialize method to do my processing.
ApplicationController:
Protected Overrides Sub Initialize(ByVal requestContext As System.Web.Routing.RequestContext)
MyBase.Initialize(requestContext)
Dim host as String
host = Request.Url.Host.ToString
End Sub
What is the logic behind having Controller Constructors fire before the Initialize method?
Also what are the rules to what should be placed in the Initialize Method.

Assuming that constructors are the first instance method ever to be fired in a .NET class, that shouldn't come as a surprise and is not really something MVC specific. It's more how the .NET framework works.
The MVC framework needs to first instantiate a controller and then initialize it => it calls the constructor first. And because performing lots of code that could potentially might throw exceptions, etc... is not always best to be put in a constructor => the presence of the Initialize method. As far as this method is concerned I must admit that I have written lots of ASP.NET MVC code and never had to use it. Action filters always seemed like a better alternative.
So to answer your question:
Also what are the rules to what should be placed in the Initialize Method.
I've never ever put any code and never ever need to override this method. I've always preferred using action filters because this way I am no longer in the obligation of deriving from a common base controller (not that this is a problem).

Sometimes, maybe you would want your request to initialize your variables, so in this case you should use the Initialize method.
For example, if you want to initialize some variables in a different way when the request is local or not, etc.

Related

ZF 2.4 - controller - alternative for init()?

I've this two lines on all the action() in the controller so I want to move it to init() so it will get called each time. It doesn't work so I tried __construct and it won't work as it says "PHP Fatal error: Uncaught Error: Call to a member function get() on null"
Maybe that can be done in factory and you still call getServiceLocator in factory class? If I can do it within controller that will be even better as that's less step to do and is that possible to do it in controller so every action will have that?
$view_helper = $this->getServiceLocator()->get('viewhelpermanager');
$view_helper->get('headScript')->appendFile(....);
Only two solutions exist:
You can do an abstract controller, and use the viewhelpermanager as dependency in your constructor. This means you will need to pass the viewhelpermanager in all the subclasses factories and not forget to call the parent construct and so on when creating the object.
You can use a delegator in the service manager and an abstract controller that contains a setViewHelperManager method and a viewhelpermanager (or worst, a trait :) and a ViewHelperManagerAwareInterface and an initializer), and do a "soft dependency", but that's a wrong way to do things in terms of maintenance (code readability).
Why don't you write your own view helper and make that include the js file(s). You can then use this in all the view.phtml files that require these files. If you need to change/add/remove js files then just do this in your view helper, obviously this change will reflect in all your views that use it.
This keeps the view stuff away from your controller.
Hope this helps.

Force .NET MVC Controller to Call Service Methods Rather Than Directly Calling Base Class

I have a standard class stack in a .NET MVC5 using Entity Framework 6:
MyController()
MyService() : ServiceBase()
ServiceBase() : IServiceBase
All methods/classes are public at the moment.
ServiceBase() contains generic(T) methods and is inherited by all services.
The problem is that MyController() can call the generic methods in ServiceBase() directly. Important properties need to be set on the Entity before being passed to ServiceBase().
Is there any way to hide the ServiceBase() methods from MyController() forcing MyController() to go through MyService() rather than calling ServiceBase() methods directly?
Thanks all.
Why are you starting from an interface? I think you are getting your OO a little confused. I think the problem you are having is that you start at an interface, which doesn't have method visiblity controls. So you try to hide it in ServiceBase, but MyService has to know about the interface so that is why you cannot change visibility midway through.
I would suggest you rethink your OO strategy a bit.
However, if you really want to keep the interface and hide the methods in the base class, you can blank them out in MyService and inside of another method of MyService you can directly call the base class. I have created an example here.
But like I said, I would discourage this behavior and come up with a better OO strategy. If you can get around to posting your code, perhaps in a separate question, then I and the rest of the community can help you out with that. FYI, this might go better in the codereview stackexchange site.
The answer is to make the base classes that I don't want the controllers to access directly abstract while continuing to contain method implementation.
Make the ServiceBase classes abstract with a protected constructor. Then only classes that derive from them can access their methods directly, forcing the controller to call the controllers service which then calls the base service classes.
I wrote all this up in a blog post here

Declaring DbContext for an MVC controller

Looking at some of the MVC examples online, I've see that typically in a controller the DbContext variable is declared as a private member variable (i.e. global) and accessible to all the methods.
But, I recently came across an article on ASP.NET Identity, and noticed in the controller, the DbContext is declared within each method (that requires it).
Is there a security benefit to this approach? Perhaps limit the lifespan of the security object(s) for better overall security?!?!
If not, then I see the first approach being more efficient, where the database context is instantiated upon the controller loading.
Below is all I could find about DbContext, but nothing to really answer my question.
DbContext declaration - Framework 4.1 - MVC 3.0
MVC, DbContext and Multithreading
On every request, a new instance of the controller is constructed. Therefore, for all intents and purposes, it does not really matter whether the dbcontext is instantiated in the constructor vs encapsulated in any given method.
Aside from a style choice, reasons to declare and contain a dbcontext in a given method is that:
Methods that do not need it will not instantiate the context, eliminating the overhead (if there is any). This can also be accomplished using a lazy initialization pattern.
The context is disposed of immediately as soon as a method is done with it, rather than at the end of the request. Generally this should not be a concern though; usually if users are waiting around for longer than a few seconds you have a bigger problem.
Different methods use different contexts.
Among others, some reasons to declare a single context and instantiate it once:
You have only one place that instantiates a context rather than many. In a typical application, most pages will need some information from the database anyway.
Methods that call other methods will not each hold on to their own instance of a context object.
You can create a base controller class that by default creates a dbcontext object, allowing you to be DRY in all inherited controllers.
Answer from #Ic. is pretty good. I wanted to add that if you need to pass information from your Request into your DbContext constructor then you need to create the instance of your DbContext inside your action methods. The reason is the Request object will be null till the control enters your action method.
More information: I had a need to build connection string dynamically depending on the location of the user. I saved the location as a cookie that I accessed through Request object. I had a valid Request inside the action method but it was null inside the constructor or at the class level properties of the controller.

What things can I put inside a BaseController to make my MVC life simpler

My base controller has:
[Authorize(Roles = "sys_admin")]
I want to have one action in a controller that's different and is available to "user" and "sys_admin". Can I override and how do I do that?
Also any suggestions on what else I could put in a base controller that might make my coding simpler. For example what's in your base controllers?
Anything that you use in every controller - attributes, methods, properties, etc. The same stuff you would put in any base class.
Just to add to the discussion, I have a few extra utility methods in my shared controller. I write a bunch of little apps for corporate use, so I try to repeat code as little as possible here.
getContext(): Puts together an object containing user info like IP, hostname, id, etc. for logging purposes.
Shared Views/Partials such as Error, Default, and Redirect (used for redirecting ajax requests).
RedirectToError(): I created this to use similar to RedirectToAction. I load up an ErrorObject with info, throw it in session, and return a Redirect to my Error page.
General logging and tracing methods so I can quickly spit out information to a file.
I override OnActionExecuting and check if my session is still valid and redirect to login if its not. Probably better with attributes...went with quick and dirty. Also trace Url.PathAndQuery for debugging here.
Any data access actions that I would use across views with ajax, like loading up a list of departments.
OnException is overridden, as well.
That's what I got in mine so far.
In my base controllers I actually put some utility method ([NonAction]) collected over time. I prefer to add functionalities to Controllers by decorating with Attributes if possible.
Lately my base controller has:
some Properties for retrieving information about the current user (my app
specific informations, not the User.Identity stuffs)
A simple protected override void OnException(ExceptionContext
filterContext); override for at least logging unhandled exception and have
some sort of automatic notifications
A bunch of Cookies related methods (WebForms auth cookies management
for example)
A bunch of usefull standard attributes (usually [Authorize], [HandleError], [OutputCache]) in its declaration.
some standard method for preparing widely used json data types on the fly (when possible I prefer to have a standard json object with ErrorCode, ErrorMessage and a UserData).
With time you'll find more and more utilities to keep with your controllers, try to keep an assembly with the simpler ones (avoiding heavy dependencies), will come handy with your next MVC projects. (the same goes for Helpers and to some degree also for EditorTemplates).
For the Authorize Attribute part, well, I think the cleanest way is to write your own AuthorizeAttribute class, specifically a NonAuthorizeAttribute. I think I've also seen it somewhere on SO.
You can also play with the Order Property of the default AuthorizeAttribute - put different Order in BaseController and in Action, in order to have Action's one executed first, but I cannot recall if you can actually break the Attributes processing chain.
Regards,
M.
We cant tell you what you need in your base controller, you have to reveal these kind of thing as you implement your controllers and see repeating code.. Dont hesitate to refactor these things to your BaseController, and keep in mind, that maybe you should have 2 or more BaseControllers, or 2-layer hierarchy of BaseControllers.
I give you two tips, what i always have in my BaseController :
super-useful helper method for interface-based model binding :
protected T Bind<T, U>()
where T : U, new()
where U : class
{
T model = new T();
TryUpdateModel<U>(model);
return model;
}
You can then have multiple "sets" of properties you want to bind in different scenarios implemented as interfaces, and simple model bind your object (even existing object, from DB) with incoming values.
2.If you use custom AcionResults (maybe your specific Json builders etc.), make your "shortcuts" methods in BaseController. Same thing as View() method is shortcut for return new ViewResult(...)
To add more to the good responses already here -
caching caching caching caching
See
Disable browser cache for entire ASP.NET website

Is an instance of my controller constructor created every time I request a new page in MVC3

I have quite a few things in the constructor of my controller. Is it the case that every time I request a new page with MVC3 then the constructor executes?
A controller instance is required to serve each request. And to obtain this instance (obviously) the controller constructor is called on each request. This being said you should avoid doing many things in this constructor. There are cases for example where for some particular action on this controller you don't need all this initialization and despite this if you put it in the constructor, it will be executed. If the tasks you perform are simply instantiating some other dependencies that your controller needs, then you shouldn't worry about performance, you should worry about properly architecting your application as this job should be handled by a DI framework.
Another common gotcha is that inside the constructor you don't yet have access to the HttpContext and some properties such as Request, Response, ... might not be available in the controller constructor. They become available in the Initialize method.
All this to say that I recommend you avoid putting code (other than storing ctor argument dependencies into private variables for injecting things like services, repositories, ...) in your constructor.
The Controller base class includes the ControllerContext which is a per-request context for a controller which includes references to HttpContext for example.
Let that sink in a moment.
It's very easy to write a custom ControllerBuilder or use the new DependencyResolver to serve up a singleton controller using your favorite DI container. But what that means is your controller may hold onto state from a previous request.
In fact, one of the most common bugs when people use Castle Windsor (which uses Singleton by default I've been told) to create their controllers is they get weird behavior.
As others have pointed out, if your controller is doing a lot of work in the constructor, refactor that work into a dependency on your controller which gets passed in via your controller's contstructor. Let's call that dependency a "service".
That service can itself be a singleton (as long as it doesn't hold onto per-request state) and you can use the DependencyResolver combined with your DI container to instantiate your controllers.
It's up to the ControllerFactory to determine this; the controller factory serves up the controller instance. You could build in the ability to cache the controller, but: it would be better not to pass those references via the ctor of the controller. It would be better to cache each reference separately, and pass to the controller during construction, and let the controller get recreated everytime. If you cache the controller, it will cache other references potentially like HttpContext, which would be not the current request.
HTH.
Yes, M Jacob and this helps us making Data Access request for new DataContext in each request and it is very efficient. it is recommended to initialize a new DataContext (in your controller constructor) in each request rather than making persistent DataContext.
Internet is stateless and the server cannot really distinguish you from any other person out there (technically speaking, ignoring sessions and cookies). You are served the content and connection with you is ended. On your new request the things start from scratch. I agree with you that inability to keep an object alive is an overhead, but even bigger overhead would be if million users made a request with a different requests to the same object. Keeping million copies of the same object is next to impossible.
Regards,
Huske

Resources