Like the other types of filters, the action filter can be added to different scope levels: Global, Action, and Controller. If we want to use our filter globally, we need to register it inside the AddControllers()
method in the Program
class:
builder.Services.AddControllers(config => { config.Filters.Add(new GlobalFilterExample()); });
But if we want to use our filter as a service type on the Action or Controller level, we need to register it, but as a service in the IoC container:
builder.Services.AddScoped<ActionFilterExample>(); builder.Services.AddScoped<ControllerFilterExample>();
Finally, to use a filter registered on the Action or Controller level, we need to place it on top of the Controller or Action as a ServiceType
:
namespace AspNetCore.Controllers; [ServiceFilter(typeof(ControllerFilterExample))] [Route("api/[controller]")] [ApiController] public class TestController : ControllerBase { [HttpGet] [ServiceFilter(typeof(ActionFilterExample))] public IEnumerable<string> Get() { return new string[] { "example", "data" }; } }
The order in which our filters are executed is as follows:
Of course, we can change the order of invocation by adding the Order
property to the invocation statement:
namespace AspNetCore.Controllers; [ServiceFilter(typeof(ControllerFilterExample), Order = 2)] [Route("api/[controller]")] [ApiController] public class TestController : ControllerBase { [HttpGet] [ServiceFilter(typeof(ActionFilterExample), Order = 1)] public IEnumerable<string> Get() { return new string[] { "example", "data" }; } }
Or something like this on top of the same action:
[HttpGet] [ServiceFilter(typeof(ActionFilterExample), Order = 2)] [ServiceFilter(typeof(ActionFilterExample2), Order = 1)] public IEnumerable<string> Get() { return new string[] { "example", "data" }; }
So, with all this in mind, we can start applying some action filters in our project.