100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
.NET Framework

Action Filters

Learn how filters let you run cross-cutting logic before and after action execution, and how the different filter types fit into the MVC pipeline.

Controllers and ActionsIntermediate10 min readJul 10, 2026
Analogies

What Filters Solve

Filters let you inject reusable, cross-cutting logic into the request pipeline at specific points around action execution, without repeating that logic inside every action method. ASP.NET MVC defines five filter types executed in a fixed pipeline order: authorization filters (IAuthorizationFilter) run first to decide whether the caller may proceed; resource filters (IResourceFilter) wrap the rest of the pipeline including model binding, useful for short-circuiting expensive work like caching; action filters (IActionFilter) run immediately before and after the action method itself; exception filters (IExceptionFilter) run only when an unhandled exception bubbles up; and result filters (IResultFilter) run immediately before and after the chosen IActionResult is executed.

🏏

Cricket analogy: It is like a match's fixed sequence of checks before a ball is bowled: the umpire verifies the bowler's run-up is legal, the field placement is checked for over-the-wicket restrictions, and only then is the delivery bowled, each check a distinct stage rather than one giant rulebook consulted at once.

Authorization and Resource Filters

Authorization filters, such as the built-in [Authorize] attribute, run before any other filter and before model binding, so they can reject a request with a 401 or 403 status as cheaply as possible, without wasting effort binding a model or hitting a database. Resource filters run just after authorization but wrap the entire remaining pipeline in a try/finally-like structure, making them the right place for logic like output caching: a resource filter can inspect an incoming request, and if a cached response already exists, it can short-circuit execution entirely by setting context.Result, skipping model binding, action execution, and result execution altogether.

🏏

Cricket analogy: It is like a ground's entry gate checking a spectator's ticket validity before they even reach the stands; an invalid ticket is turned away immediately, long before they could occupy a seat that could have gone to a paying fan.

csharp
public class LogExecutionTimeAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        context.HttpContext.Items["StopwatchStart"] = DateTime.UtcNow;
    }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        var start = (DateTime)context.HttpContext.Items["StopwatchStart"]!;
        var elapsedMs = (DateTime.UtcNow - start).TotalMilliseconds;
        var logger = context.HttpContext.RequestServices
            .GetRequiredService<ILogger<LogExecutionTimeAttribute>>();
        logger.LogInformation("{Action} took {Elapsed}ms",
            context.ActionDescriptor.DisplayName, elapsedMs);
    }
}

[LogExecutionTime]
public IActionResult Search(string query) => View(_catalog.Search(query));

Action, Exception, and Result Filters

An IActionFilter implementation's OnActionExecuting runs after model binding but before the action method body, making it the ideal place to validate ModelState globally or to short-circuit with a custom result if validation fails, while OnActionExecuted runs right after the action returns, giving access to the produced result or any exception via context.Exception before it propagates further. Exception filters only fire when an exception escapes the action and any earlier filters without being handled, letting you centralize error-to-response mapping (for example, converting a domain-specific NotFoundException into a 404 ObjectResult) instead of wrapping every action body in try/catch. Result filters then wrap the execution of the IActionResult itself, useful for tasks like adding a response header or wrapping every successful JSON payload in a consistent envelope shape.

🏏

Cricket analogy: It is like a third umpire reviewing a run-out decision only when the on-field call is challenged, stepping in exclusively for that edge case rather than reviewing every single delivery of the match.

Filters can be applied at three scopes: directly on an action method, on the controller class (applying to every action in it), or globally via options.Filters.Add(...) in MVC configuration, which applies to every controller in the application. Global filters run outermost relative to controller- and action-scoped filters of the same type.

Filters vs Middleware

Filters are often confused with ASP.NET Core middleware, but they operate at different layers: middleware sits in the general HTTP pipeline and runs for every request regardless of whether MVC routing matches anything, while filters run specifically within the MVC action-invocation pipeline and have access to MVC-specific context like ActionDescriptor, ModelState, and the chosen IActionResult, none of which middleware can see directly. This means authentication middleware typically runs earliest to populate HttpContext.User, while an [Authorize] authorization filter downstream then makes the MVC-specific decision of whether that authenticated user may invoke a particular action.

🏏

Cricket analogy: It is like the difference between a stadium's general security perimeter that checks every visitor regardless of which stand they are headed to, versus a specific stand's usher who only checks tickets for that particular section's premium seats.

Do not use exception filters as a substitute for proper error handling middleware like UseExceptionHandler for global, application-wide error pages; exception filters only see exceptions thrown within the MVC action pipeline and will not catch exceptions from middleware that runs before routing, such as authentication or static file middleware.

  • ASP.NET MVC defines five filter types with a fixed order: authorization, resource, action, exception, and result filters.
  • Authorization filters run earliest and can reject a request before model binding wastes any effort.
  • Resource filters can short-circuit the entire remaining pipeline, making them ideal for caching.
  • Action filters wrap the action method itself via OnActionExecuting/OnActionExecuted.
  • Exception filters centralize error-to-response mapping but only catch exceptions from within the MVC pipeline.
  • Result filters wrap execution of the chosen IActionResult, useful for adding headers or envelope formatting.
  • Filters can be scoped to an action, a controller, or globally, and differ from middleware in having access to MVC-specific context.

Practice what you learned

Was this page helpful?

Topics covered

#NETFramework#ASPNETMVCStudyNotes#MicrosoftTechnologies#ActionFilters#Action#Filters#Solve#Authorization#StudyNotes#SkillVeris