在aspnet核心web api项目中,我有以下逻辑
if(!_entityService.Exists(entityId))
return NotFound($"{entityId} not found.");分散在许多端点/控制器上。我想将这个横切关注点重构为一个属性,例如一个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.");
}
}在控制器中使用尝试的应用程序:
class EntitiesController
{
[HttpGet("{id:int}")]
public Entity Get([FromRoute] [EntityExists] int id)
{
// no need to clutter here with the 404 anymore
}
},尽管这似乎不起作用,-端点仍然会返回400个坏请求。
在asp.net核心web中可以/建议这样做吗?我曾经考虑过使用中间件/动作过滤器,但也看不出如何从这些过滤器中实现上述目标。
发布于 2022-01-30 05:04:19
您可以定制ActionFilter属性,如下所示:
public class CustomActionFilter:ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
var entityId = int.Parse(context.HttpContext.Request.RouteValues["id"].ToString());
var entityService = context.HttpContext.RequestServices.GetService<EntityService>();
if (!entityService.Exists(entityId))
{
context.HttpContext.Response.StatusCode = StatusCodes.Status404NotFound;
context.Result = new NotFoundObjectResult($"{entityId} not found.");
}
base.OnActionExecuting(context);
}
}主计长:
[HttpGet("{id:int}")]
[CustomActionFilter]
public void Get([FromRoute] int id)
{
// no need to clutter here with the 404 anymore
}结果:

https://stackoverflow.com/questions/70910506
复制相似问题