Archive for the 'MSDN' Category

08
Jul

ASP.NET MVC - Action Filters

When developing an ASP.NET MVC application, where all user and model interaction is routed through a controller, you will no doubt have some degree of common behavior that you’d like to prevent from being replicated across multiple action methods. This could be handled any number of ways, such as creating helper classes that your action logic makes use of, or creating base controller classes that provide shared behaviors to subtypes.

While both of those solutions have their place, neither are by any means a silver bullet. If you go the helper class route, while you’ve moved the shared behavior into a central location, you’re still going to have to repeatedly call into the helper from within the body of every action that wants to make use of it. While that isn’t horrible in itself, sometimes the common logic you wish to leverage doesn’t naturally fit with the domain/space a controller or action is responsible for.

For example, imagine that you have a UserController that is responsible for handling all requests for interacting with the user model. Simple enough. Now imagine that the customer wants to have an auditing system in place that logs every request/interaction with the UserController. If you starting placing calls to your logging system within the confines of your action methods, it would only litter and confuse the true purpose of the controller, which is to orchestrate user-interaction with user data. This is what is called a cross-cutting concern, a problem that is handled nicely by Aspect-Oriented Programming (AOP) patterns.

Essentially what we need to do in this situation is have some way to associate our logic behavior with all action methods we want to use it, but without having to explicitly place the code that uses it within the body of the action. In addition, we’d need to be able to specify whether we want the shared logic to execute before or after the action method has executed. We could use an AOP framework to achieve this, but wouldn’t it be great if ASP.NET MVC itself provided such a feature?

ASP.NET MVC has the notion of action filters that represent “hooks” you can add to a controller or action that allow you to perform arbitrary logic before and after the execution of the action method as well as the action result. In its simplest form, an action filter is a class that implements the IActionFilter interface, which contains four self-explanatory virtual methods (just begging to be overriden):

  1. OnActionExecuted
  2. OnActionExecuting
  3. OnResultExecuted
  4. OnResultExecuting

Out-of-the-box, ASP.NET MVC provides two classes that implement the IActionFilter interface: Controller, and ActionFilterAttribute. Because the Controller class is itself an action filter, you can insert pre/post logic into the pipeline on an ad-hoc basis for a specific controller by simply overriding one or more of the four aforementioned methods. Using the above example, if I wanted to log data directly before an action was executed, as well as directly after its corresponding action result was executed, I could do something similar to the following:

public class UserController : Controller 
{ 
    protected override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
        // Run pre logging code 
    }       
 
    protected override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
        // Run post logging code 
    }       
 
    // Action methods 
}

Now our action methods are free to be concerned with only their responsibility, while the filters handle any supporting concerns. This is useful, but doesn’t serve our problem when we want our logic to be shared by many different controller actions. We could create a base controller that is used by all other controllers in our application, but what if we only want the filter logic to be performed by select actions on a controller? Further still, we might feel that placing these cross-cutting concerns directly within our controller doesn’t feel natural to our situation. This is where the ActionFilterAttribute comes in handy.

The ActionFilterAttribute is simply a class that inherits from Attribute and implements IActionFilter. It has the same four methods (pre/post hooks) as mentioned above, and any (or all) can be easily overridden. The ActionFilterAttribute is great because it encapsulates the concerning logic completely, masking its internals from either the controller or the action. In order to use it all you have to do is attach it to either a controller (which will apply that filter to all child actions) or to a specific action method. This allows a level of granularity and abstraction that using the Controller itself as a filter doesn’t. We could port the above sample to use ActionFilterAttributes like so:

[LoggingActionFilter] 
public class UserController : Controller 
{ 
    // Action methods 
}       
 
public class LoggingActionFilterAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
        // Run pre logging code 
    }       
 
    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
        // Run post logging code 
    } 
}

Now our controller is free of all logic it isn’t (and arguably shouldn’t be) concerned with. Alternatively, if we didn’t want to have a filter affect all actions within a controller, instead of attaching the filter to the controller itself, we could salt an action method with it, like so:

public class UserController : Controller 
{ 
    [LoggingActionFilter] 
    public ActionResult Index() 
    { 
        // Action logic 
    }       
 
    // Additional Action methods 
}

I could now begin associating my new logging filter with any action or controller that needed its logic, without having to replicate any code, or clutter my controller.

What happens though when I want to associate numerous action filters to a controller/action? Because they’re just attributes, I can attach as many filters as I want:

[LoggingActionFilter] 
[AuthenticationActionFilter] 
[SomeOtherActionFilter] 
public ActionResult Index() 
{ 
    // Action logic 
}

In the above example, it wouldn’t make sense to perform logging logic when the authentication filter might cause the user to be redirected to another action (or controller). In this case, what we’d need is some way to specify an order of operations for our filters. Luckily, the ActionFilterAttribute has a property that allows us to explicitly set on order. By default, the filters are executed top down (well kind of), so in our case, LoggingActionFilter would run, then AuthenticationActionFilter, and finally SomeOtherActionResult. I said “kind of” because this isn’t behavior you should be relying on, and isn’t documented or expected to always work this way. If the execution order of you filters matter, you should be explicitly setting it, like so:

[LoggingActionFilter(1)] 
[AuthenticationActionFilter(0)] 
[SomeOtherActionFilter(2)] 
public ActionResult Index() 
{ 
    // Action logic 
}

Now we have full control over what order the filters run in. You may be wondering how the order of filters works if you have filters applied at both the controller and action level (and potentially even by overriding the Controller’s filter methods). For instance, what if I had code similar to the following:

[LoggingActionFilter] 
public class UserController : Controller 
{ 
    protected override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
        // Arbitrary logic 
    }       
 
    [AuthenticationActionFilter] 
    public ActionResult Index() 
    { 
        // Action logic 
    }       
 
    // Additional Action methods 
}

What order are those three filters run in? The overriden Controller methods are always first, so in our case, the OnActionExecuted method would have precedence regardless what order you specify on your filter attributes. Second, all controller-level filter attributes are run. Their order of execution is subject to the same rules mentioned above for action-level filter attributes. Finally, all action-level filter attributes are executed.

Action filters represent a reusable piece of functionality that can leveraged by many different applications needing to take advantage of common concerns without directly adding that logic within their own code base. You can expect to see lots of interesting filters surface over time by both the community as well as third-parties.

07
Jul

ASP.NET MVC - ControllerActionInvoker: Part 2

In the last post, I introduced the specific roles that the ControllerActionInvoker plays in the ASP.NET MVC execution pipeline, and showed how you would inject a custom invoker into your controller (via a controller factory, or custom controller). In this post, I’m going to further clarify some of the juicy details…

<important_paragraph>

After the ASP.NET Routing engine intercepts a request and hands it off to the appropriate controller, the controller grabs the name of the requested action method and asks its ControllerActionInvoker to execute it. As far as the controller is concerned, it has no idea of the concept of an action filter or an action result. All of that logic is embodied within the ControllerActionInvoker. All the controller cares about is that the invoker executes the action it asked it to.

</important_paragraph>

You may be asking why the above paragraph is so important, and if you are then that sucks because I obviously failed at making the really cool point clear. Many people I’ve spoken with have asked me why the controller doesn’t just execute the action itself, since it “houses” the method and could easily handle that responsibility. Which makes total sense, since we’re talking about some extremely basic reflection to find the method, and then invoke it. But, like was mentioned in the above paragraph, more is involved then just that, and you don’t want the controller having to be concerned with the additional “fluff”.

For the record, as far as the core ASP.NET MVC runtime knows, the controller is actually handling all of the request execution logic. This is made clear by looking at the IController interface, which has a single method: Execute. It’s important to understand that this article is talking about the specific Controller class’s implementation of the IController interface.

When the controller hands the request off to its invoker it is basically saying “I don’t give a crap what you do or how you do it, just find this action, and give the client what they want”. The invoker then looks at its controller with a maniacal grin on his (or hers) face and says “Sure, I’ll take care of it muahahaha!”.

Why this is interesting is because it builds additional abstraction on top of what is called a Front Controller. In Martin Fowler’s definition of a front controller, you have an entity (handler) that watches incoming requests and determines which command can and will serve an individual request. Applying this to our situation, the Handler is ASP.NET Routing, and the Command is IController.

image

Front Controller (Martin Fowler)

The core ASP.NET MVC runtime is itself a front controller implementation. Once we introduce the Controller class though, with its ControllerActionInvoker counterpart, we now effectively have a two-tiered front controller. The outer Handler is still played by ASP.NET Routing, and IController still plays the Command, but because we’re using the Controller implementation, it in turns spawns it own front controller type pattern. The ControllerActionInvoker effectively becomes a Handler as well, one that routes action requests instead of controller requests. The commands that the invoker routes to are ActionResult instances.

This additional separation of concerns (yes I had to say it), makes it possible to add any additional logic that your heart desires within a custom ControllerActionInvoker without having the muddy the controller waters. The architectural pattern (front controller) remains in tact, but your implementation has the freedom to run wild, which is pretty awesome :)

03
Jul

ASP.NET MVC - ControllerActionInvoker: Part 1

Whenever I give a session on ASP.NET MVC I always make a point to highlight the extensibility pipeline and how easily you can replace the default behavior/conventions with just about anything you can imagine (you should be happy with your code right?). I tend to focus on controller factories, action results, action filters, and view engines as the primary candidates for extension, because those enable a whole slew of fairly common scenarios for developers. But I’d hate to feel like I’m playing favorites…

While I was in Sydney last month, one of the attendees at an ASP.NET MVC session I was giving asked me when and why you would ever create your own custom ControllerActionInvoker, which I thought was a great question, and one that I foolishly haven’t been discussing. I’d hate to feel like I’m skirting over any interesting details, so I’m going to put together a couple of blog posts to showcase creating a custom ControllerActionInvoker.

The first thing to tackle when thinking about reasons to extend the ControllerActionInvoker class is to understand what exactly its role is in the overall request execution process. This diagram shows a decent (emphasis on decent) illustration of where the invoker sits in the lifecycle:

img-07-03-2008.png

Notice that the invoker comes into the picture based on its association with the Controller. By this, I specifically mean the Controller class, so if you create your own IController implementation, the ControllerActionInvoker isn’t in the picture anymore (unless you leverage it from your implementation as well). When a controller’s Execute method is called (by the routing engine), the controller grabs its invoker and passes the request on to it. So it isn’t actually the Controller class that executes its own actions, it is its invoker that does. This may sound a little strange, but it makes sense as you dig deeper…

Once the invoker has received “focus” from the controller, it essentially has five tasks that it attempts to perform, all of which represent a possible point of extension, and can be used to enable some pretty interesting stuff:

  1. Retrieve a MethodInfo that represents the requested action method
  2. Determine where to retrieve values for the action method’s parameters (if any exist)
  3. Get a list of all action filters associated with the action method
  4. Execute the action method (along with any filters)
  5. Execute the action result (along with any filters)

So how does this process play out in the default invoker implementation? If the controller’s ActionInvoker property isn’t specifically set, it news up an instance of the ControllerActionInvoker class, and hands it the reigns. It’s behavior aligns to the above five steps as follows:

  1. The invoker reflects against its parent controller, looking for a public method with the exact name of the requested action. The method can’t be static, have generic parameters, or be salted with the NonAction attribute.
  2. The invoker looks to see if the method has any parameters (can’t be out/ref) and if so, looks for values with the same name as the parameter in the following locations (in this order):
    1. Route value
    2. Query String
    3. Form
    4. Cookie
    5. Server variable
  3. The invoker looks for filters that are represented as attributes that were appended to the action method (and inherit from ActionFilterAttribute), as well as its parent controller
  4. This is a three step process:
    1. Call the OnActionExecuting method of all action filters associated with the action
    2. Execute the actual action method (capturing the returned ActionResult for later use)
    3. Call the OnActionExecuted method of all action filters associated with the action
  5. This is a three step process:
    1. Call the OnResultExecuting method of all action filters associated with the action
    2. Call the ActionResult’s ExecuteResult method
    3. Call the OnResultExecuted method of all action filters associated with the action

If we determine that we want to replace one of those steps with our own behavior, how can we go about doing that? All we have to do is subclass ControllerActionInvoker, and assign an instance of our invoker to the controller’s ActionInvoker property, so that it uses our implementation instead of the default. When deciding how we’d like to inject our custom invoker, we have two choices:

  1. Create a custom controller factory
  2. Create a custom controller

If you decide to create a custom controller factory, the easiest path to take would be to create a class that inherits from DefaultControllerFactory (provides a lot of useful functionality on top of IControllerFactory), and override its GetControllerInstance method, where you would create an instance of your invoker, and inject it into the created controller, like so:

public class CustomFactory : DefaultControllerFactory 
{ 
    protected override IController GetControllerInstance(Type controllerType) 
    { 
        var controller = (Controller)base.GetControllerInstance(controllerType); 
        controller.ActionInvoker =
            new CustomInvoker(new ControllerContext(base.RequestContext, controller)); 
        return controller; 
    } 
}

Then you would inject your custom controller factory into the pipeline by letting the ControllerBuilder know you want to use it, by putting the following code in application start in your Global.asax file:

ControllerBuilder.Current.SetControllerFactory(typeof(CustomFactory));

This approach works great if you want all controllers in your web application to automatically receive the custom invoker. But, maybe you want your controllers to have to “opt-in” to leveraging the custom invoker, which is when creating a custom controller might work better, because then your controllers would have to specifically inherit from the custom controller class in order to receive the custom invoker.

Because the invoker relies on ControllerContext, which isn’t provided to the Controller class until its Execute method is called, if you choose to subclass the Controller class, you can simply override its Execute method. This allows you to new up an instance of our custom invoker, leveraging the provided ControllerContext, like so:

public class CustomController : Controller 
{ 
    protected override void Execute(ControllerContext controllerContext) 
    { 
        ActionInvoker = new CustomInvoker(controllerContext); 
        base.Execute(controllerContext); 
    } 
}

Now when I create a new controller, instead of inheriting from the Controller class, I can just inherit from CustomController, and benefit from my custom invoker:

public class HomeController : CustomController 
{ 
	// Action methods... 
}

Now that we’ve discussed what responsibilities the ControllerActionInvoker actually has, and where it rests in the pipeline, in the next few blog posts we’ll see what kind of scenarios we can enable by replacing some of the default behavior with our own.