Create your own Action Filter for your ASP.NET Core Application


Action Filters in ASP.NET Core allow code to run before or after specific stages in the request processing pipeline of the app. On this post, I'll guide you how to create your first action filter for your ASP.NET Core Application.

Nov. 30, 2021

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.

Steps in Creating Simple Custom Action Filter
Step 1: Create your method and inherit the 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.

Step 2: Register inside the ConfigureServices in Startup.cs
        services.AddScoped<PersonIdFilter>();
      

Step 3: Use it in your Controller Method
        [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!

If you have some questions or comments, please drop it below 👇 :)

Buy Me A Tea