In this post, we will see how to create an Action Filter in a .NET 5 Web API project.
First of all, what is an Action Filter?
“An Action filter runs the code immediately before and after the controller action method is called. It can be used to perform any action before or after execution of the controller action method. We can also manipulate the arguments passed into an action”.
For example we could use an Action Filter to check a property of an entity only for a specific method and, for this reason, we cannot insert it in a Data Annotation.
Using the project created in Web API – Custom Data Annotation, we will add a new check for the property Title of the entity Document.
We start modifying the method called NewDocument in the DocumentController:
[HttpPost]
[Route("/v1/document")]
public IActionResult NewDocument(Document inputDocument)
{
try
{
_documentControllerService.InsertDocument(inputDocument);
return Ok();
}
catch
{
return BadRequest();
}
}
If we run the method, this will be the result:
Now, we create a new class called CheckDocumentTitleInput (derived from ActionFilterAttribute) where we will override the method OnActionExecuting:
[CHECKDOCUMENTTITLEINPUT.CS]
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using OData_Post.Domain.Entities;
using ActionFilterAttribute = Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute;
namespace CustomDataAnnotaion_Post.Domain.ActionFilter
{
public class CheckDocumentTitleInput : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
// we take the object passed in input
var documentInput = context.ActionArguments["inputDocument"] as Document;
// we verify that Title is greater that 5 characters
if(documentInput != null && documentInput.Title.Length<5)
{
// we create a Bad Request Result
context.ModelState.AddModelError("DocumentError", "The Title parameter must be greater than 5 characters");
context.Result = new BadRequestObjectResult(context.ModelState);
}
}
}
}
Finally, we add a new method called NewDocumentWithCheck in DocumentController where we will put the Action Filter “CheckDocumentTitleInput”:
[HttpPost]
[Route("/v2/document")]
[CheckDocumentTitleInput]
public IActionResult NewDocumentWithCheck(Document inputDocument)
{
try
{
_documentControllerService.InsertDocument(inputDocument);
return Ok();
}
catch
{
return BadRequest();
}
}
We have done and now, if we run the new method, this will be the result: