This article provides an overview of IActionFilter in ASP.NET Core Web API, focusing on its execution order, attribute usage, and registration methods. The environment used is VS2019 with ASP.NET Core 3.1.
- Execution Order of IActionFilter
The filter is called after the controller's constructor is executed.
The OnActionExecuting method of IActionFilter runs before the action method is invoked, and the OnActionExecuted method runs after the action method completes.
- Attribute Usage
(1) Direct Attribute Application
This approach requires that the IActionFilter subclass has a parameterless constructor.
[HttpGet]
[Route("Info")]
[CustomActionFilter]
public string Info()
{
return "test info";
}
(2) Using TypeFilter Attribute
In this case, the IActionFilter subclass can have a constructor that accepts services, and there is no need to register the filter service in Startup.
[HttpGet]
[Route("Info")]
[TypeFilter(typeof(CustomLogFilter))]
public string Info()
{
return "test info";
}
(3) Using ServiceFilter Attribute
With this method, the IActionFilter subclass can also accept services via the constructor, but it must be rgeistered as a service in Startup.
[HttpGet]
[Route("Info")]
[ServiceFilter(typeof(CustomLogFilter))]
public string Info()
{
return "test info";
}
// Registering the filter service
services.AddSingleton<CustomLogFilter>();
- Registration Methods
(1) Method-Level Registration
[HttpGet]
[Route("Info")]
[ServiceFilter(typeof(CustomLogFilter))]
public string Info()
{
return "test info";
}
(2) Controller-Level Registration
[Route("api/[controller]")]
[ApiController]
[ServiceFilter(typeof(CustomLogFilter))]
public class FilterController : ControllerBase
{
}
(3) Global Registration
// Register the filter service
services.AddSingleton<CustomLogFilter>();
// Add the filter globally
services.AddMvc(options =>
{
options.Filters.Add(typeof(CustomLogFilter));
});
(4) Notes
When using method-level, controller-level, and global registrations together, the execution order is:
Global Filter OnActionExecuting ->
Controller Filter OnActionExecuting ->
Method Filter OnActionExecuting ->
Execute API method ->
Method Filter OnActionExecuted ->
Controller Filter OnActionExecuted ->
Global Filter OnActionExecuted
Which follows this pattern:
OnActionExecuting (Global -> Controller -> Method) ->
Execute API method ->
OnActionExecuted (Method -> Controller -> Global)