w3resource

ASP.NET MVC - Action Filters


In the previous tutorials, you learned about filters and filter registration in an ASP.NET MVC application. In this tutorial, you will learn Action Filters and how to use them in our application.

Action filter are filters that executes before and after an action method is called. Action filter attributes can either be applied to an individual action method or to a controller. When an action filter is applied to a controller then it will be applied to all the action methods of that controller but when applied to a method, it becomes specific for that method.

We will illustrate these action filters with a built-in action filter called OutputCache. OutputCache is a built-in action filter attribute that can be applied to an action method for which we want to cache the output. For instance, output of the following action method will be cached for 70 seconds.

Example: ActionFilter

[OutputCache(Duration=70)]
public ActionResult Home()
{
    return View();
}

Aside the built-in action filters, we can create custom action filters for out application. Don't worry, I will show you how to do that in the next paragraph.

How to create Custom Action Filter

To create custom action filters, we can create custom action filter in two ways.

  • Implementing IActionFilter interface and FilterAttribute class.
  • Deriving ActionFilterAttribute abstract class.

Implementing the IActionFilter interface includes implementing the following methods:

  1. void OnActionExecuted(ActionExecutedContext filterContext)
  2. void OnActionExecuting(ActionExecutingContext filterContext)

While deriving the ActionFilterAttribute abstract class includes overriding the following methods:

  1. void OnActionExecuted(ActionExecutedContext filterContext)
  2. void OnActionExecuting(ActionExecutingContext filterContext)
  3. void OnResultExecuted(ResultExecutedContext filterContext)
  4. void OnResultExecuting(ResultExecutingContext filterContext)

As you can see that ActionFilterAttribute class has four methods to override. It includes OnResultExecuted and OnResultExecuting methods, which can be used to execute custom logic before or after result executes. Action filters are generally used to apply cross-cutting concerns such as logging, caching and authorization.

Consider the following custom Logging filter class for logging.

Example: Custom ActionFilter for Logging

public class LogAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Logging("OnActionExecuted", filterContext.RouteData); 
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Logging("OnActionExecuting", filterContext.RouteData);      
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        Logging("OnResultExecuted", filterContext.RouteData);      
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        Logging("OnResultExecuting ", filterContext.RouteData);      
    }

    private void Logging(string methodName, RouteData routeData)
    {
        var controllerName = routeData.Values["controller"];
        var actionName = routeData.Values["action"];
        var message = String.Format("{0}- controller:{1} action:{2}", methodName, 
                                                                    controllerName, 
                                                                    actionName);
        Debug.WriteLine(message);
    }
}

As you can see, Logging class derived ActionFilterAttribute class. It logs before and after action method or result executes. You can apply Log attribute to any Controller or action methods where you want to log the action. For example, by applying Log attribute to Controller, it will log each action methods of that controller.

Example: Apply Logging ActionFilter to Controller

[Logging]
public class ActivitiesController : Controller
{
    public ActionResult Home()
    {
        return View();
    }
    public ActionResult About()
    {
        return View();
    }
    public ActionResult Contact()
    {
        return View();
    }
}

The above example will show following output in the output window of Visual Studio on http://localhost/activities request.

Output:

OnActionExecuting-controller:Homeaction:Home
OnActionExecuted-controller:Homeaction:Home
OnResultExecuting-controller:Homeaction:Home
OnResultExecuted- controller:Home action:Home