When I first started building ASP.NET Core APIs, I noticed a pattern.
Many controller actions contained the same code:
- Validate requests.
- Check permissions.
- Log execution time.
- Handle exceptions.
- Write audit logs.
The APIs worked.
But every new endpoint meant copying the same logic again.
That’s when I discovered Filters.
I realized they weren’t just another ASP.NET Core feature—they were a way to keep controllers focused on business logic while moving cross-cutting concerns to reusable components.
What Are Filters?
Filters allow you to execute code before or after an action method runs.
Instead of repeating common logic in every controller, you write it once and apply it wherever it’s needed.
Types of Filters
Authorization Filter
Runs first and determines whether the request is authorized.
Example:
- Check user permissions.
- Validate custom authorization rules.
Resource Filter
Executes before model binding.
Useful for:
- Caching
- Short-circuiting requests
- Resource initialization
Action Filter
Runs before and after the controller action.
Common use cases:
- Input validation
- Logging
- Measuring execution time
- Auditing
Exception Filter
Handles exceptions thrown by controller actions.
Useful for:
- Logging exceptions
- Returning consistent error responses
Result Filter
Runs before and after the action result is executed.
Useful for:
- Modifying response headers
- Wrapping API responses
- Adding metadata
When Should You Use Filters?
Filters are ideal for logic that applies across multiple endpoints.
Examples include:
- Audit logging
- Request validation
- Performance monitoring
- Response formatting
- Custom authorization
If you find yourself copying the same code into multiple controllers, it’s often a sign that a filter could help.
When Should You Avoid Filters?
Filters aren’t the answer for every problem.
Choose the right tool for the job:
- Middleware for application-wide concerns such as authentication, CORS, or request logging.
- Filters for MVC or API action-specific behavior.
- Services for business logic.
Keeping these responsibilities separate leads to a cleaner architecture.
Final Thoughts
One lesson changed the way I structure APIs:
Controllers should coordinate requests—not perform every supporting task themselves.
Filters help eliminate duplication, improve maintainability, and keep your business logic where it belongs.






