Roadmap › ASP.NET Core MVC (and Razor Pages) › Module: Filters, State and Security
Lessons in this course (15)

11. Filters and their order

Intermediate★ Must knowLesson 11 of 15
FilterRunsExample
AuthorizationFirst; can short-circuit[Authorize], custom policy checks
ResourceBefore/after model bindingCaching, short-circuit for maintenance
ActionBefore/after the action methodLogging, validation, modifying arguments
ExceptionWhen an unhandled exception occurs in the MVC pipelineConvert to error view/ProblemDetails
ResultBefore/after the result executesAdd headers, modify the result
csharp
public class AuditFilter(ILogger<AuditFilter> log) : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext ctx, ActionExecutionDelegate next)
    {
        log.LogInformation("Executing {Action}", ctx.ActionDescriptor.DisplayName);
        var executed = await next();
        if (executed.Exception is null) log.LogInformation("Done {Action}", ctx.ActionDescriptor.DisplayName);
    }
}
builder.Services.AddControllersWithViews(o => o.Filters.Add<AuditFilter>());   // global
// or [ServiceFilter(typeof(AuditFilter))] on a controller/action (filter resolved from DI)

Scope order: global → controller → action on the way in (reverse on the way out); override with Order.

Filters vs middleware: middleware sees every request (including static files) and knows nothing about MVC; filters run only for MVC actions and have access to ModelState, action arguments and results.