Click here to Skip to main content
15,867,895 members
Articles / Web Development / HTML

A Beginner's Tutorial for Understanding Filters and Attributes in ASP.NET MVC

Rate me:
Please Sign up or sign in to vote.
4.89/5 (82 votes)
14 Apr 2013CPOL6 min read 358.2K   7.9K   80   22
In this article we will try to see how we can use custom filters and attributes in an ASP.NET MVC application.

Introduction

In this article we will try to see how we can use custom filters and attributes in an ASP.NET MVC application. Custom filters and attributes are an excellent way of injecting extra processing logic into the MVC request response pipeline. We will try to understand all about these and will see them in action using a simple sample application.

Background

In an ASP.NET MVC application the request from the user first lands at the UrlRoutingModule. This module parses the requested URL and then invokes the corresponding controller and action. The controller will then render the appropriate view and the response will be sent to the user.

Now what if we want to inject some extra processing logic in this request-response life cycle. Some extra logic that is written once and can be reused across multiple controllers and/or actions.

ASP.NET MVC provides a way for us to do that by writing custom filters that can be used to inject extra processing logic in the request-response life cycle.

What are attributes and filters

MVC provides a very clean way of injecting the pre-processing and post-processing logic for actions and controllers. They way we can put the pre-processing and post-processing logic is by decorating the actions with attributes which will invoke an attribute class implementing the filter's logic.

For example, If we need some action to be executed when the user has been authenticated then we can adorn the action with the [Authorize] attribute. This will take care of calling the attribute class which implements the authorization filter to check whether the user has is authorized or not.

C#
[Authorize]
public ActionResult Index()
{
    return View();
}

So the way to implement custom filters would be to implement the interface that is needed for implementing the required filter. Now we can decorate the actions with this attribute so that our filter logic will be executed when this action is called. If we want all the actions of a controller to use this filter we can decorate the controller itself with this attribute.

Using the code

Let us now try to look at the type of filters we can implement to inject our custom processing logic.

Type of filters

Now taking this discussion further, Let us first discuss the various types of filters that can be implemented to inject custom processing logic.

  • Authorization filter
  • Action filter
  • Result filter
  • Exception filter

Implementing Custom Filters

Now let us try to look at implement these filters. We will simply implement the custom filters and put a simple message in the ViewBag collection. We will then use these filters with an action of controller and try to see the custom messages we inserted in the ViewBag collection on our view page.

Authorization filter

This filter provides authentication and authorization logic. It will be executed before the action gets executed. To implement this action the interface IAuthorizationFilter should be implemented by the custom attribute class.

C#
public class CustomAuthorizationAttribute : FilterAttribute, IAuthorizationFilter
{
    void IAuthorizationFilter.OnAuthorization(AuthorizationContext filterContext)
    {
        filterContext.Controller.ViewBag.OnAuthorization = "IAuthorizationFilter.OnAuthorization filter called";
    }
}

Now when we decorate the action method with this attribute the OnAuthorize filter method will be called and our custom logic will get executed.

Note: In the above code we have created an attribute which will only run when the authorization is being done by the application. In our own filter method we are not doing anything related to authorization. If we were to do custom authentication and authorization then we will have to derive this attribute from AuthorizeAttribute class and implement custom authorization logic. Perhaps we will discuss that separately. For now this filter will run run when the authorization is being done and before calling the action method so that we can inject our custom logic in it.

Action filter

This filter will be called before and after the action starts executing and after the action has executed. We can put our custom pre-processing and post-processing logic in this filter.

Now to implement this filter we need to create a custom filter attribute class and implement the

IActionFilter
filter interface. This interface provides us two methods OnActionExecuting and OnActionExecuted which will be called before and after the action gets executed respectively.

C#
public class CustomActionAttribute : FilterAttribute, IActionFilter
{
    void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
    {
        filterContext.Controller.ViewBag.OnActionExecuted = "IActionFilter.OnActionExecuted filter called";
    }

    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.Controller.ViewBag.OnActionExecuting = "IActionFilter.OnActionExecuting filter called";
    }
}

Result filter

This filter will execute before and after the result of the action method has been executed. We can use this filter if we want some modification to be done in the action's result.

To implement the result filters we need to create a custom filter attribute class and implement the

IResultFilter
interface. this interface provides two methods OnResultExecuting and OnResultExecuted which will be called before and after the action result respectively.

C#
public class CustomResultAttribute : FilterAttribute, IResultFilter
{
    void IResultFilter.OnResultExecuted(ResultExecutedContext filterContext)
    {
        filterContext.Controller.ViewBag.OnResultExecuted = "IResultFilter.OnResultExecuted filter called";
    }

    void IResultFilter.OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.Controller.ViewBag.OnResultExecuting = "IResultFilter.OnResultExecuting filter called";
    }
}

Exception filter

This filter will be invoked whenever a controller or action of the controller throws an exception. This is particularly useful when we need custom error logging module.

To implement this filter we need to create a custom filter attribute class which implements IExceptionFilter. This interface gives us a methods called OnException which is a perfect place to call the exception logging module and to redirect to some error page.

public class CustomExceptionAttribute : FilterAttribute, IExceptionFilter
{       
    void IExceptionFilter.OnException(ExceptionContext filterContext)
    {
        filterContext.Controller.ViewBag.OnException = "IExceptionFilter.OnException filter called";
    }
}

Order of Execution

Now with all the above filters we have the following filter methods.

  • IAuthorizationFilter.OnAuthorization
  • IActionFilter.OnActionExecuted
  • IActionFilter.OnActionExecuting
  • IResultFilter.OnResultExecuted
  • IResultFilter.OnResultExecuting
  • IExceptionFilter.OnException

Now assuming that we have all the filters attached to a single action method what will be the order of execution of these filers. These filters will execute in following order under normal(non-exception) scenario.

  1. IAuthorizationFilter.OnAuthorization
  2. IActionFilter.OnActionExecuting
  3. IActionFilter.OnActionExecuted
  4. IResultFilter.OnResultExecuting
  5. IResultFilter.OnResultExecuted

In case there is an exception, OnException will will be called as instead of the result filters.

Using the Custom Filters

Now from our application we just need to decorate the actions on which we need the custom filter functionality. Lets try to do this on a single action method as:

C#
public class HomeController : Controller
{   
    [CustomAuthorization]
    [CustomAction]
    [CustomResultAttribute]
    [CustomExceptionAttribute]
    public ActionResult Index()
    {
        //throw new Exception("Dummy Exception");
        ViewBag.Message = "Index Action of Home controller is being called.";
        return View();
    }
}

And the code to see these on the view page:

Image 1

And when we try to run the application:

Image 2

The important thing to note in the running application is that ViewBag.OnResultExecuted is empty. the reason for this is that the function IResultFilter.OnResultExecuted gets called when the view has been rendered i.e. the action result has been completed.

Note: It is advisable to put breakpoints on all filter methods and then run the application to understand the sequence of these filter methods. Also, un-commenting the line in controller which throws a dummy exception will invoke the IExceptionFilter.OnException filter method too.

Built-in Attributes 

ASP.NET MVC comes with a some of built in attribute classes that provides a some boilerplate functionality. We can create custom classes that derives from these built in classes and further provide specialized behavior as per our needs. Let us try to see some of these built in attributes.

  • AuthorizeAttribute: MVC framework provides AuthorizeAttribute which is helpful in specifying our custom authorization policies.
  • ActionFilterAttribute: This is the built in implementation of IActionFilter and IResultFilter. This attribute can be used as base class to implement the custom behavior for action and result filters.
  • HandleErrorAttribute: This is the built in implementation of IExceptionFilter which makes it easier to implement the exception handling strategy.

Point of interest 

This was an introductory article for beginner's to make then familiar with the concept of filters and attributes in ASP.NET MVC application. We discussed how custom filters and attributes are helpful in injecting custom pre-processing and/or post-processing logic in the MVC request-response cycle. I hope this has been little informative. 

History

  • 15 April 2013: First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
India India

I Started my Programming career with C++. Later got a chance to develop Windows Form applications using C#. Currently using C#, ASP.NET & ASP.NET MVC to create Information Systems, e-commerce/e-governance Portals and Data driven websites.

My interests involves Programming, Website development and Learning/Teaching subjects related to Computer Science/Information Systems. IMO, C# is the best programming language and I love working with C# and other Microsoft Technologies.

  • Microsoft Certified Technology Specialist (MCTS): Web Applications Development with Microsoft .NET Framework 4
  • Microsoft Certified Technology Specialist (MCTS): Accessing Data with Microsoft .NET Framework 4
  • Microsoft Certified Technology Specialist (MCTS): Windows Communication Foundation Development with Microsoft .NET Framework 4

If you like my articles, please visit my website for more: www.rahulrajatsingh.com[^]

  • Microsoft MVP 2015

Comments and Discussions

 
QuestionAuthorize Vs Exception filter Pin
Member 118513837-Jul-17 17:35
Member 118513837-Jul-17 17:35 
QuestionNice explanation Pin
chirag7mca28-Sep-16 20:54
chirag7mca28-Sep-16 20:54 
QuestionNice Article Rajat Need one clarification. Pin
Member 1191277415-Sep-16 19:54
Member 1191277415-Sep-16 19:54 
GeneralMy vote of 5 Pin
Pratik Bhuva8-Aug-16 20:53
professionalPratik Bhuva8-Aug-16 20:53 
GeneralNice Explanation Pin
Alireza_136217-Feb-16 10:46
Alireza_136217-Feb-16 10:46 
Thanks!

QuestionVery Clear Explanation Pin
Member 1190517715-Jan-16 6:01
Member 1190517715-Jan-16 6:01 
Questionthanks Rahul Pin
Badar Yousaf16-Feb-15 0:38
Badar Yousaf16-Feb-15 0:38 
QuestionPassing more useful data Pin
CockroachCoader30-Oct-14 21:59
CockroachCoader30-Oct-14 21:59 
Questionaction Filter Pin
Member 1102927822-Aug-14 0:12
Member 1102927822-Aug-14 0:12 
AnswerRe: action Filter Pin
Rahul Rajat Singh22-Aug-14 0:21
professionalRahul Rajat Singh22-Aug-14 0:21 
GeneralMy vote of 5 Pin
Paul Sincai27-May-14 20:25
Paul Sincai27-May-14 20:25 
GeneralMy vote of 5 Pin
Renju Vinod28-Apr-14 22:57
professionalRenju Vinod28-Apr-14 22:57 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun12-Mar-14 22:32
Humayun Kabir Mamun12-Mar-14 22:32 
GeneralMy vote of 5 Pin
Amey K Bhatkar15-Jan-14 0:50
Amey K Bhatkar15-Jan-14 0:50 
GeneralMy vote of 5 Pin
Genius4IT16-Dec-13 1:11
Genius4IT16-Dec-13 1:11 
QuestionExcellent job Pin
Member 165621414-Dec-13 8:18
Member 165621414-Dec-13 8:18 
GeneralExcellent Pin
Sridhar Patnayak2-Dec-13 19:43
professionalSridhar Patnayak2-Dec-13 19:43 
GeneralThanks Pin
Member 1002829521-Nov-13 6:49
Member 1002829521-Nov-13 6:49 
GeneralNice Example Pin
upenn875-Nov-13 19:08
upenn875-Nov-13 19:08 
GeneralNice Post Pin
AnujSharma_bbd24-Oct-13 8:15
AnujSharma_bbd24-Oct-13 8:15 
AnswerArticle of the Day on Microsoft's site Pin
Rahul Rajat Singh1-May-13 18:38
professionalRahul Rajat Singh1-May-13 18:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.