Filters

Filters in ASP.NET Core MVC are the places where we can run the code before or after the action execution in the request processing pipeline. Filters run within the MVC action invocation pipeline, also known as filter pipeline. This pipeline comes into View after the framework chooses the action to be executed.

The following list view code map diagram illustrates the actors involved in filters:

On the right, we have attributes defined, which are abstract classes. On the left, there are abstractions and context classes. The filters execute at different stages in the action execution pipeline, based on the type of filter, which can be:

  • Authorization filters: These are the implementation of IAuthorizationFilter/IAsyncAuthorizationFilter and are run first to determine if the current user is authorized or not. They can short circuit the pipeline if the user in unauthorized.
  • Resource filters: These are the implementation of IResourceFilter/IAsyncResourceFilter and are run immediately after the authorization filters. When these filters execute, model binding has not taken place in the pipeline so they can be used to alter the model binding. The most common use of these filters is that of caching.
  • Action filters: These filters are the implementation of IActionFilter / IAsyncActionFilter or ActionFilterAttribute and are run immediately before and after an action execution. Due to their location in the pipeline, they are well-suited for any manipulation to action method parameters as well as to returned results from the action.
  • Exception filters: These filters are the implementation of IExceptionFilter / IAsyncExceptionFilter or ExceptionFilterAttribute and are used to apply exception handling to the code before the response is written.
  • Result filters: These are the implementation of IResultFilter / IAsyncResultFilter or ResultFilterAttribute and are run immediately before and after the execution of individual action results. They are run only if the action method successfully executes.

If we look closely, we can notice that there are multiple ways to implement the filter. There is filter interface, then there is async filter interface, and we have abstract attribute classes that we can implement. The framework first checks if the filter implements an async interface. If it does, it calls the async methods of the filter. If not, it calls the non-async methods, so either an async or synchronous interface should be implemented. If we implement both, only the async implementation would be called. This is also the case when we implement the abstract class. To summarize, the following is what the filter pipeline looks like:

We should write our custom filters based on the preceding flow, so that the desired operation code can be written at the right place in the filter pipeline. Next, we will see an implementation of the sample filter and different ways to implement a filter.

  1.  Derive from Attribute and implement IActionFilter—filters are implemented as attributes and hence we need to derive from Attribute and implement IActionFilter for the class to be treated as a filter:
using Microsoft.AspNetCore.Mvc.Filters; //// required namespace

public class BookPublishingFilter: Attribute, IActionFilter
{
public void OnActionexecuting(ActionExecutingContext context)
{
//// Write code to be executed, before the action method is
called.
}

public void OnActionexecuted(ActionExecutedContext context)
{
//// Code to be executed, after the action method is called.
}
}
  1. Derive from ActionFilterAttribute—the ActionFilterAttribute class already derives from the Attribute class and implements IActionFilter and hence we can directly derive from ActionFilterAttribute and create a filter attribute. So, the preceding code would remain the same apart from the base class and interface with which we need to derive:
using Microsoft.AspNetCore.Mvc.Filters; //// required namespace

public class BookPublishingFilter: ActionFilterAttribute
{
public void OnActionexecuting(ActionExecutingContext context)
{
//// Write code to be executed, before the action method is
called.
}

public void OnActionexecuted(ActionExecutedContext context)
{
//// Code to be executed, after the action method is called.
}
}

There are few other ways to define the action filters, but we will not discuss them here. They can be seen from the reference link shared towards the end of the section. Likewise, Exception filters can be created by deriving from ExceptionFilterAttribute, ResultFilter by deriving from ResultFilterAttribute, and so on.

For consuming the filters, they can be registered globally in the ConfigureServices method in the Startup.cs or by decorating the filter attribute in the controller or action, which is shown as follows:

//// Register the filter globally. This would be invoked for all 
controller actions.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.Filters.Add(typeof(BookPublishingFilter)); // by type
//// Use either above line or below line, not both. Here both
are shown to demonstrate ways in which it can be done.
options.Filters.Add(new BookPublishingFilter()); // an instance
});
}

//// Register the filter only at action where it is needed. If it is
applied in controller, it applies to all actions.
[BookPublishingFilter]
public IActionResult GetUnpublishedBooks()
{
}

Since the filters can be registered both globally and at action level also, a definite question comes to mind, which is: in what order do they execute? The answer is simple:

  • The action executing method of global filters runs first, then of action executing methods of filters registered at controller runs, and finally action executing methods of filters registered at action level.
  • While returning from action, the order is the other way round. The action executed method of filter registered at action level runs first, then action executed method of filter registered at controller level, and finally the action executed method of filter registered globally.
  • This is also referred to as Nesting Doll or Russian Doll model.
  • This is the default behaviour. ASP.NET Core provides a way to override the default order of execution by implementing IOrderedFilter, which exposes an Order property, specifying which can override the default order of execution. 

For a detailed and thorough discussion on filters, please read the documentation of filter at: https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters.

With this note, we will move on to our next topic: Controllers.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.61.16