Asp.Net Core Filters

1. The Problem

Imagine an ASP.NET Core Web API with dozens of controllers and endpoints.

Several endpoints need to perform common work:

  • Check whether the request is authorized.
  • Validate incoming data.
  • Log execution details.
  • Handle certain exceptions.
  • Run something before or after an action executes.

For example:

POST   /api/orders
GET    /api/orders/123
PUT    /api/orders/123
DELETE /api/orders/123

You could put the same logic inside every controller action. But that quickly becomes repetitive.

CreateOrder()
   +-- check something
   +-- log something
   +-- execute business logic
   +-- handle something

UpdateOrder()
   +-- check something
   +-- log something
   +-- execute business logic
   +-- handle something

DeleteOrder()
   +-- check something
   +-- log something
   +-- execute business logic
   +-- handle something

Now imagine changing that common behavior. You have to find every action that contains it.

The controller starts becoming responsible for things that aren't really part of the business operation.


2. What's Actually Going Wrong?

The problem is cross-cutting concerns are getting mixed into controller actions.

A controller action should primarily deal with the request and the application operation it represents.

CreateOrder()
     |
     v
Create the order

But if the action also contains:

CreateOrder()
   +-- authorization check
   +-- logging
   +-- validation
   +-- exception handling
   +-- business logic
   +-- response creation

the action becomes harder to understand and maintain.

ASP.NET Core provides Filters to move certain types of cross-cutting behavior outside the action itself.


3. The Concept

An ASP.NET Core Filter allows you to run code at specific points around MVC controller/action execution.

Conceptually:

HTTP Request
   |
   v
ASP.NET Core Pipeline
   |
   v
Controller Filters (Before Action)
   |
   v
Controller Action
   |
   v
Controller Filters (After Action)
   |
   v
HTTP Response

The filter gets an opportunity to participate in processing without putting the same logic directly inside every controller action.


4. What Types of Filters Are Available?

ASP.NET Core provides several filter types, each operating at a different stage.

HTTP Request
     |
     v
Authorization Filters
     |
     v
Resource Filters
     |
     v
Action Filters
     |
     v
Controller Action
     |
     v
Exception Filters
     |
     v
Result Filters
     |
     v
HTTP Response

The exact MVC pipeline has additional details, but this gives you the useful mental model.

Authorization Filters

These run early and are concerned with whether the request is allowed to proceed.

Request
   |
   v
Authorization Filter
   |
   +-- Not allowed --> Stop
   |
   +-- Allowed -----> Continue

ASP.NET Core's authorization system, including [Authorize], is the normal place to handle authorization requirements.

The important point is:

Don't put authorization checks manually inside every controller action when ASP.NET Core's authorization mechanisms already provide the appropriate pipeline behavior.

Resource Filters

Resource filters run around much of the MVC processing and can execute before model binding.

They can be useful when you need to control behavior at a point that is earlier than action execution.

Think of them as a broader boundary around MVC resource processing.

Action Filters

Action filters run immediately around controller action execution.

Before Action
      |
      v
Controller Action
      |
      v
After Action

They are useful for cross-cutting behavior such as:

  • Logging action execution
  • Measuring execution time
  • Applying common action-level behavior
  • Performing reusable checks that genuinely belong at the action boundary

The important benefit is that the controller action can stay focused on its actual operation.

Exception Filters

Exception filters allow you to participate in handling exceptions thrown during MVC action execution.

Controller Action
      |
      | exception
      v
Exception Filter
      |
      v
HTTP Response

However, exception filters are not the universal exception-handling mechanism for an entire ASP.NET Core application.

For application-wide exception handling, ASP.NET Core's exception-handling middleware is often the more appropriate architectural choice.

That distinction matters.

Result Filters

Result filters run around the execution of an MVC action result.

Controller Action
      |
      v
Action Result
      |
      v
Result Filter
      |
      v
HTTP Response

They are useful when the concern specifically relates to processing the action result.


5. How Do You Use Filters?

The important architectural question isn't:

“How do I create a filter?”

It is:

“Is this behavior really an MVC action concern?”

If yes, a filter can be a good fit.

Logging every controller action
            |
            v
       Action Filter

Instead of:

CreateOrder()
   +-- logging
   +-- business logic
   +-- response

UpdateOrder()
   +-- logging
   +-- business logic
   +-- response

You can keep the controller focused:

Action Filter
     |
     v
CreateOrder()
     |
     v
Business Logic

Filters can be applied at different scopes, such as:

  • Globally
  • To a controller
  • To a specific action

This allows you to decide how broadly the behavior should apply.


6. Filters vs Middleware

This is one of the most important distinctions for an ASP.NET Core engineer.

Both can run code around requests, but they operate at different levels.

Middleware

Middleware operates in the ASP.NET Core request pipeline.

HTTP Request
     |
     v
Middleware
     |
     v
Routing
     |
     v
MVC
     |
     v
Controller

Middleware is therefore appropriate for concerns that apply broadly across the application. Examples:

  • Global exception handling
  • Request/response logging
  • Authentication-related pipeline behavior
  • Correlation IDs
  • General HTTP concerns

Filters

Filters operate within the MVC/controller pipeline.

HTTP Request
     |
     v
ASP.NET Core
     |
     v
MVC
     |
     v
Filters
     |
     v
Controller Action

They are appropriate when the concern is specifically related to MVC action execution.

The Mental Model

ASP.NET Core
     |
     v
 Middleware
     |
     v
    MVC
     |
     v
  Filters
     |
     v
Controller Action

So don't automatically create a filter just because you want reusable request logic. First ask:

Does this belong to the overall HTTP pipeline, or specifically to MVC/action execution?

7. Filters vs Business Logic

Filters should not become a dumping ground for business rules.

For example, suppose you have:

OrderService
    +-- calculate price
    +-- apply discount
    +-- check inventory
    +-- create order

These are business/application responsibilities. They shouldn't be moved into an Action Filter simply because the logic is reusable.

A better separation is:

Controller
    |
    v
  Filter
    |    (cross-cutting MVC concern)
    v
Controller Action
    |
    v
Application / Domain Logic

Filter: “Something that needs to happen around the action.”

Service: “Something that the application needs to do.”

That distinction keeps the architecture clean.


8. When Should You Use It?

Use ASP.NET Core Filters when:

  • The concern is closely related to MVC/controller execution.
  • The same behavior applies to multiple actions.
  • You need behavior before or after an action.
  • You need action-level exception/result processing.
  • You want to avoid duplicating cross-cutting MVC behavior.

Typical examples include:

Action Filters
    +-- Action-level logging
    +-- Execution timing
    +-- Common MVC behavior

Authorization Filters
    +-- Authorization-related processing

Exception Filters
    +-- MVC-specific exception handling

Result Filters
    +-- Action-result processing

9. What Happens If You Use Filters for Everything?

You can end up with a controller where the actual behavior is difficult to discover.

Request
  |
  v
Filter A
  |
  v
Filter B
  |
  v
Filter C
  |
  v
Middleware
  |
  v
Another Filter
  |
  v
Controller

A developer looking at the controller may not realize that several important things happen before or after the action.

Filters should therefore be used deliberately. A useful rule is:

Use a filter when the behavior naturally belongs around MVC action execution, not simply because the behavior is reusable.

10. Visualize It in Everyday Terms

Think about a restaurant. A customer enters the restaurant and eventually reaches the waiter who takes the order.

There are different checks and activities around that interaction.

Customer
   |
   v
Entry Check
   |
   v
Table Preparation
   |
   v
Waiter Takes Order
   |
   v
Order Processing
   |
   v
Bill / Result

Mapping this to ASP.NET Core:

  • Entry Check → Authorization Filter
  • Table Preparation → Resource Filter
  • Before taking order → Action Filter
  • Taking the order → Controller Action
  • Handling an issue → Exception Filter
  • Preparing the bill → Result Filter

The key idea is:

Filters let you attach reusable behavior around a specific stage of MVC processing without putting that behavior inside every controller action.

11. What Should You Remember?

Don't think:

“Filters are a way to avoid writing duplicate code.”

Think:

“Filters are hooks into the ASP.NET Core MVC execution pipeline.”

Remember the distinction:

Middleware
    |    (application-wide HTTP pipeline)
    v
   MVC
    |    (MVC-specific pipeline)
    v
 Filters
    |
    v
Controller Action

And remember:

  • Authorization Filter → Is the request allowed to proceed?
  • Resource Filter → Behavior around MVC resource processing.
  • Action Filter → Behavior around controller action execution.
  • Exception Filter → MVC-specific exception handling.
  • Result Filter → Behavior around action-result execution.

12. .NET + Azure Context

In a typical ASP.NET Core Web API hosted in Azure, the architecture might look like:

Azure
   |
   v
ASP.NET Core API
   |
   v
Middleware
   |
   v
MVC
   |
   v
Filters (Authorization / Resource / Action)
   |
   v
Controller Action
   |
   v
Application Service
   |
   v
EF Core / Azure SQL

Relevant .NET building blocks include:

  • ASP.NET Core MVC
  • IAuthorizationFilter
  • IResourceFilter
  • IActionFilter
  • IExceptionFilter
  • IResultFilter
  • Attribute-based filters such as [Authorize]
  • ASP.NET Core middleware
  • Dependency Injection for filter dependencies

In Azure, the API might be hosted on:

  • Azure App Service
  • Azure Container Apps
  • Azure Kubernetes Service

The hosting platform doesn't change what a filter is. The important architectural point is:

ASP.NET Core Filters are an MVC-level extension point. Use them for concerns that belong around controller/action execution, while keeping application and business logic in the appropriate services.

Application: ASP.NET Core / .NET

Pattern: Filters (Authorization, Resource, Action, Exception, Result)

Key interface: IResourceFilter

Main benefit: Keep cross-cutting MVC concerns out of controller actions

Main concern: Not a substitute for application-wide middleware or for business logic in services

Middleware handles the broad HTTP pipeline. Filters handle MVC-specific behavior. Services handle application/business logic.