
Filters in ASP.NET Core offer an advantage if you use it properly. As a matter of fact, there's built-in filters that handle tasks such as: Authorization and Response caching. Custom filters can also be created to handle cross-cutting concerns like error handling, caching, configuration, authorization, and logging.
Not all filter executes at the same in the filter pipeline but each filter type is executed at a different stage. As you can see at the image below: Authorization filters run first followed by Resource filters and so on and so forth.
To learn more, visit this link from official Microsoft Docs: Filters in ASP.NET Core In this post, I'll guide you step by step on how to create basic action filter that checks if the id is already exist inside our record.
IAsyncActionFilter using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace ActionFilterSampApp
{
public class PersonIdFilter : IAsyncActionFilter
{
private readonly RecordDbContext recordDbcontext;
public PersonIdFilter(RecordDbContext recordDbcontext)
{
this.recordDbcontext = recordDbcontext;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
try
{
if (context.ActionArguments.ContainsKey("id"))
{
var id = (int)context.ActionArguments["id"];
var person = await recordDbcontext.Person.FirstOrDefaultAsync(x => x.PersonId == id);
if (person == null) {
context.Result = new NotFoundResult();
return;
}
}
await next();
}
catch (Exception e)
{
context.Result = new BadRequestObjectResult($"Something went wrong. {e.Message}");
return;
}
}
}
}
In the code example above, we are using the IAsyncActionFilter but if you're working with synchronous, you can use the IActionFilter interface.
IAsyncActionFilter has only one require method which is the OnActionExecutionAsync compare to IActionFilter which has 2 contracts that need to be implemented. These are the OnActionExecuted: a method before action executes and the OnActionExecuted: after the action executes.
services.AddScoped<PersonIdFilter>();
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
[ServiceFilter(typeof(PersonIdFilter))]
public async Task<IActionResult> Get(int id)
{
// do something...
}
[ServiceFilter(typeof(PersonIdFilter))]
public async Task<IActionResult> Put(int id)
{
// do something...
}
}
Depending on your requirement: You can also create the other filters and use it above your controller so that filter can be automatically applied to its methods.
I hope this post helps you. Have a good day!