In February 2017, the Manning Early Access Program (MEAP) started for the ASP.NET Core book I am currently writing - ASP.NET Core in Action. This post is a sample of what you can find in the book. If you like what you see, please take a look - for now you can even get a 37% discount with the code lockaspdotnet!
The Manning Early Access Program provides you full access to books as they are written, You get the chapters as they are produced, plus the finished eBook as soon as it’s ready, and the paper book long before it's in bookstores. You can also interact with the author (me!) on the forums to provide feedback as the book is being written.
The book is now finished and completely available in the MEAP, so now is the time to act if you're interested! Thanks 🙂
Understanding filters and when to use them
The MVC filter pipeline is a relatively simple concept, in that it provides “hooks” into the normal MVC request as shown in figure 1. For example, say you wanted to ensure that users can only create or edit products on an ecommerce app if they’re logged in. The app would redirect anonymous users to a login page instead of executing the action.
Without filters, you’d need to include the same code to check for a logged in user at the start of each specific action method. With this approach, the
MvcMiddleware still executes the model binding and validation, even if the user wasn’t logged in.
With filters, you can use the “hooks” into the MVC request to run common code across all, or a sub-set of requests. This way you can do a wide range of things, such as:
- Ensure a user is logged in before an action method, model binding or validation runs
- Customize the output format of particular action methods
- Handle model validation failures before an action method is invoked
- Catch exceptions from an action method and handle them in a special way
Figure 1 Filters run at multiple points in the MvcMiddleware in the normal handling of a request.
In many ways, the MVC filter pipeline is like a middleware pipeline, but restricted to the
MvcMiddleware only. Like middleware, filters are good for handling cross-cutting concerns for your application, and are a useful tool for reducing code duplication in many cases.
The MVC filter pipeline
As you saw in figure 1, MVC filters run at a number of different points in the MVC request. This “linear” view of an MVC request and the filter pipeline that we’ve used this far doesn’t quite match up with how these filters execute. Five different types of filter, each of which runs at a different “stage” in the
MvcMiddleware, are shown in figure 2.
Each stage lends itself to a particular use case, thanks to its specific location in the
MvcMiddleware, with respect to model binding, action execution, and result execution.
- Authorization filters – These run first in the pipeline, and are useful for protecting your APIs and action methods. If an authorization filter deems the request unauthorized, it short-circuits the request, preventing the rest of the filter pipeline from running.
- Resource filters – After authorization, resource filters are the next filters to run in the pipeline. They can also execute at the end of the pipeline, in much the same way middleware components can handle both the incoming request and the outgoing response. Alternatively, they can completely short-circuit the request pipeline, and return a response directly. Thanks to their early position in the pipeline, resource filters can have a variety of uses. You could add metrics to an action method, prevent an action method from executing if an unsupported content type is requested, or, as they run before model binding, control the way model binding works for that request.
- Action filters – Action filters run before and after an action is executed. As model binding has already happened, action filters let you manipulate the arguments to the method, before it executes, or they can short-circuit the action completely and return a different
IActionResult. As they also run after the action executes, they can optionally customize the
IActionResultbefore it’s executed.
- Exception filters – Exception filters can catch exceptions that occur in the filter pipeline, and handle them appropriately. They let you write custom MVC-specific error handling code, which can be useful in some situations. For example, you could catch exceptions in Web API actions and format them differently to exceptions in your MVC actions.
- Result filters – Result filters run before and after an action method’s IActionResult is executed. This lets you control the execution of the result, or even short-circuit the execution of the result.
Figure 2 The MVC filter pipeline, including the five different filters stages. Some filter stages (Resource, Action, Result filters) run twice, before and after the remainder of the pipeline.
Exactly which filter you pick to implement depends on the functionality you’re trying to introduce. Want to short-circuit a request as early as possible? Resource filters are a good fit. Need access to the action method parameters? Use an action filter.
You can think of the filter pipeline as a small middleware pipeline that lives by itself in the
MvcMiddleware. Alternatively, you could think of them as “hooks” into the MVC action invocation process, which let you run code at a particular point in a request’s “lifecycle.”