What is the use of ControllerActionInvoker class?
Basically it's an extensibility point on a Controller class that allows you to get in there and influence how the controller interacts with Parameters, Filters and the Action itself. When a request has been routed to the Controller, the Controller asks the ControllerActionInvoker to deal with the request (which normally involves it calling a method back on the Controller).
The main usage of this I've seen so far is to provide dependency injection into Action Filters as shown here, but I'm sure we'll see more uses for this feature popping up in the future!
Related
I've not looked at the AutoMapper source code yet but was just about to make some changes to an API controller in my solution and had a thought.
The way I like to code is to keep my controller methods as concise as possible, for for instances I make use of a generic Exception attribute to handle try{}catch{} scenarios.
So only the code that is absolutely relevant to the controller action is actually in the action method.
So I just arrived at a situation where I need to create an AutoMapper map for a method. I was initially thinking that I would add this (as I have done previously) to the controller constructor so its available immediately.
However, as the controller grows following this pattern may introduce a lot unnecessary AutoMapper work depending on the controller action method which is invoked.
Considering controllers are created and destroyed per request this could get expensive.
What are some recommendations around this? Considering AutoMapper is accessed statically I was wondering if it's internals live beyond the request lifetime and it internally checks for an existing map before creating a new one each time CreateMap() is invoked?
You should create your maps (CreateMap) once per AppDomain, ideally when this domain starts (Application_Start).
A discussion came up at work recently about why ASP.NET MVC doesn't use static methods for its controller methods. Whilst I was on the side of the fence against using static methods, the only two arguments I could think for non-static action methods were inheritence and the ability to mock (which inheritence gives you).
What was Microsoft's design choice for non-static actions/methods over static?
While I don't know minds of those that designed the ASP.NET MVC Framework here is the big one for me:
An instance controller is instantiated once per request, multiple requests can be happening simultaneously. If a controller is static then any state on the controller is shared across all requests simultaneously. You probably don't want that. Updating that shared state becomes a minefield of locking contention, possible deadlocks and very hard to track bugs if locking isn't implemented properly.
In short, a static controller would be a nightmare to work with.
You have for example controller "Home" and action "FillData",
and another controller "Student" and action "FillData".
Imagine what will happen if you make action "FillData" a static method, and could be called in any other controller easily.
It would be a big ISSUE.
I have an ASP.NET MVC application with a controller that looks something like this:
[Authorize]
public class MyController : Controller
{
IMyRepository myRepository;
public MyController(IMyRepository myRepository)
{
this.myRepository = myRepository;
}
...
}
I have noticed that this constructor gets called prior to authenticating the user, so if you are visiting the page for the first time the constructor is called prior to redirecting you to the login screen. There are many problems with this, the login page loads slower, the site has greater exposure to DOS attacks, and I'm a little nervous about unauthenticated, unauthorized users being able to invoke code 'behind the walls' sort of speak.
I could check the incomming request in the constructor and bail unless the user is authorized, but I'm using IOC (Windsor) which makes that a bit tricky, my repository is going to be initialized regardless of whether or not I store the instance, so I'd be left checking authentication in each repository's constructor. Is there an easy way to get .NET MVC to authenticate the user prior to invoking the constructor? I'm thinking something like adding [PrincipalPermission(SecurityAction.Demand, Authenticated = true)] to the controller, but there might be a better way still.
EDIT:
Ok, not too happy about it, but the show must go on for now. I cannot delay initializing the repository until some later point in time from within the controller. When your controller uses IOC as in my example, you get an already instantiated implementation of your repository interface at the time that the controller is instantiated. If I had control over the repository being created, I could easily just call IsAuthenticated, no need for a new method. In order to take control of the repository initialization you would have to implement some sort of lazy/late initialization in the repository itself in each implementation. I do not like this solution because it adds needless complexity and more importantly coupling between the controller and repository. The repository implementation(s) may be used in other contexts where lazy initialization doesn't make sense IMHO.
The controller needs to be instantiated before authorization happens because it can act as its own authorization filter via the OnAuthorization method. Changing that behavior would involve replacing some core parts of the mvc pipeline. Is there a particular reason why you think the AuthorizedAttribute might not do its job?
Another option you could consider is initializing your repository in the OnActionExecuting of your controller method instead of in the constructor.
You can use HttpModules (or HttpHandler) to authenticate the request earlier in the pipeline.
MSDN: Introduction to HTTP Modules
MSDN: Implementing Intercepting Filter in ASP.NET Using HTTP Module
EDIT
With the introduction of OWIN you can configure the entire request pipeline middleware and put authorization at whatever stage you want. Same idea as above but a bit easier to implement.
Paul,
the instantiation of the controller is many many processes ahead of any actions on the controller being callable. even if the would be attacker attempted to benefit from this time lapse between instantiation and the login-screen, the controller action would only be able to run if the action had the authority to do so i.e. i'm assuming that your actions or controller all have the [Authorize] attribute on them.
I don't think you need worry too much about this and can rest easy, tho' i understand your obvious curiosity.
In terms of DOS attacks, it really should not matter -- after the first hit, which one sees alot when developing, the controller instantiation should be cheap. Well, unless you are DDOSing yourself by having the constructor do actual work such as pre-caching database lookups . . .
I'm in the process of developing my MVC application and I was thinking, What is the lifetime of a controller class?
When does it get created? How many instances of a single controller are there? what are the implications of local variables? when is it destroyed?
I'm sure there is a good link somewhere floating around on the internet, but my google-fu couldn't find it.
Stephen Walther has a great article on the life-cycle of a request being handled by the MVC Framework.
Here's a extract from the top of his article, it goes on to explain each step in detail:
Overview of the Lifecycle Steps
There are five main steps that happen when you make a request from an ASP.NET MVC website:
1. The RouteTable is Created
This first step happens only once when an ASP.NET application first starts. The RouteTable maps URLs to handlers.
2. The UrlRoutingModule Intercepts the Request
This second step happens whenever you make a request. The UrlRoutingModule intercepts every request and creates and executes the right handler.
3. The MvcHandler Executes
The MvcHandler creates a controller, passes the controller a ControllerContext, and executes the controller.
4. The Controller Executes
The controller determines which controller method to execute, builds a list of parameters, and executes the method.
5. The RenderView Method is Called
Typically, a controller method calls RenderView() to render content back to the browser. The Controller.RenderView() method delegates its work to a particular ViewEngine
Assuming you don't change the default ControllerFactory, controllers will be created for every request and will be garbage collected "sometime after" the request has completed.
In short, you don't need to worry about race conditions for instance variables (though you do for static variables, obviously). Having said that, I'd recommend keeping your controller actions reentrant for the sake of cleaner code.
I'm running into an issue with the Policy Injection Application Block from Enterprise Library in conjunction with ASP.NET MVC.
In my ControllerFactory, I'm creating the controller and then calling PolicyInjection.Wrap on the controller. This gives me back a Transparent Proxy to the controller which manages the call handler chain.
Finally, I cast the Transparent Proxy to an IController and return it.
This seems to work well, except that none of the call handlers I've defined for my controller are executing. (For example I have a Logging Handler configured, but nothing is being logged by PIAB.)
Is my final cast messing this up somehow? How does ControllerBase.Execute() call into my controller? It seems like my proxy should be utilized. Anyone using PIAB on ASP.NET controllers?
I am using PIAB to wrap ASP.NET MVC Controllers, and I'm doing so by calling
PolicyInjection.Wrap<IController>(instance)
which will wrap the IController methods. I'm also using policy injection to wrap the IActionInvoker that gets used as well, which allows for logging the action name.
I have not had success wrapping controllers using the MarshalByRefObject wrapping, but the interface wrapping works like a charm.
If you want additional information, you could create an interface that has all the methods from IController, IActionFilter, IAuthorizationFilter, IExceptionFilter and IResultFilter and then have your controllers implement that interface. Then you could wrap your controllers as that interface and get more calls going through policy injection.
I hope that helps. If you have more specific issues please post.
Seems at least one person uses it :) - ASP.NET MVC Validation using Policy Injection Application Block in Enterprise Library (this is first result BTW)