Building Custom Action Filters in ASP.NET MVC

ASP.NET MVC gives you a clean separation of concerns — but sometimes, you’ll need to execute certain logic before or after a controller action runs.

For example:

  • Logging user activity
  • Validating input
  • Measuring performance
  • Handling custom authorization

Instead of repeating the same code in every controller, Action Filters let you inject that behavior globally, per controller, or per action.

In this post, we’ll explore what action filters are, how they work, and how to create your own custom filter in ASP.NET MVC.


What Is an Action Filter?

An Action Filter is an attribute you can apply to a controller or action method to run custom logic at specific points in the request pipeline.

ASP.NET MVC provides several built-in filters:

  • AuthorizeAttribute
  • HandleErrorAttribute
  • OutputCacheAttribute
  • ActionFilterAttribute

But you can also create your own by inheriting from ActionFilterAttribute and overriding its methods.


The Filter Lifecycle

Action filters can hook into different stages of the MVC request lifecycle:

MethodDescription
OnActionExecuting()Runs before the action method executes
OnActionExecuted()Runs after the action method executes
OnResultExecuting()Runs before the result (e.g., a view) is executed
OnResultExecuted()Runs after the result has been executed

This gives you full control over both the action logic and the result rendering phases.


Creating a Custom Action Filter

Let’s build a simple custom filter that logs when an action starts and ends.

Step 1: Create a new class

using System;
using System.Diagnostics;
using System.Web.Mvc;

public class LogActionFilter : ActionFilterAttribute
{
    private Stopwatch stopwatch;

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        stopwatch = Stopwatch.StartNew();
        Debug.WriteLine($"[Log] Action '{filterContext.ActionDescriptor.ActionName}' started at {DateTime.Now}");
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        stopwatch.Stop();
        Debug.WriteLine($"[Log] Action '{filterContext.ActionDescriptor.ActionName}' completed in {stopwatch.ElapsedMilliseconds} ms");
    }
}

Step 2: Apply It to a Controller or Action

You can decorate an entire controller or just a specific action.

Apply to an action:

public class HomeController : Controller
{
    [LogActionFilter]
    public ActionResult Index()
    {
        return View();
    }
}

Apply to a controller:

[LogActionFilter]
public class ProductsController : Controller
{
    public ActionResult List()
    {
        return View();
    }

    public ActionResult Details(int id)
    {
        return View();
    }
}

Now every time an action runs, your filter will log the start and end times.


Step 3: Register Globally (Optional)

If you want the filter to apply to every action in your app, register it globally in FilterConfig.cs:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new LogActionFilter());
    }
}

And in Global.asax:

FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
Home » Building Custom Action Filters in ASP.NET MVC