In an aspnet core web api project I have the logic
if(!_entityService.Exists(entityId))
return NotFound($"{entityId} not found.");
Scattered across many endpoints/controllers. I would like to refactor this cross-cutting concern to an Attribute, example a ValidationAttribute:
class EntityExistsAttribute : ValidationAttribute
{
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
{
var entityId = (int)value;
var entityService = validationContext.GetRequiredService<EntityService>();
if(entityService.Exists(entityId))
return ValidationResult.Success;
var httpContext = validationContext.GetRequiredService<IHttpContextAccessor>().HttpContext;
httpContext.Response.StatusCode = StatusCodes.Status404NotFound;
return new ValidationResult($"{entityId} not found.");
}
}
With the attempted application in a controller:
class EntitiesController
{
[HttpGet("{id:int}")]
public Entity Get([FromRoute] [EntityExists] int id)
{
// no need to clutter here with the 404 anymore
}
}
Though this doesn't seem to work - the endpoint will still return 400 Bad Request.
Is it possible/advised to do anything like this in an asp.net core web api? I have thought about using middleware/action filters but couldn't see how I would achieve the above from those either.