[英]Triggering InvalidModelStateResponseFactory when ModelState is invalid
我正在使用 asp.net 核心 3.0 编写 API 并为我的应用程序配置了所有控制器的以下行为:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.ConfigureApiBehaviorOptions(setupAction =>
{
setupAction.InvalidModelStateResponseFactory = context =>
{
var problemDetails = new ValidationProblemDetails(context.ModelState)
{
Type = "https://courselibrary.com/modelvalidationproblem",
Title = "One or more model validation errors occurred.",
Status = StatusCodes.Status422UnprocessableEntity,
Detail = "See the errors property for details",
Instance = context.HttpContext.Request.Path
};
problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);
return new UnprocessableEntityObjectResult(problemDetails)
{
ContentTypes = { "application/problem+json" }
};
};
});
...
}
这适用于我的输入(例如: [Required]
)类的属性上的数据注释。 如果任何注释失败,它会返回一个 422 Unprocessable Entity 响应,如下所示:
{
"type": "https://courselibrary.com/modelvalidationproblem",
"title": "One or more model validation errors occurred.",
"status": 422,
"detail": "See the errors property for details",
"instance": "/api/songbooks/21924d66-dac6-43a5-beee-206de4d35216/songs",
"traceId": "0HLQFGSFIFL5L:00000001",
"errors": {
"Title": [
"The Title field is required."
]
}
}
但是,我在我的 controller 中实现 FluentValudation,如下所示:
if (!newSong.IsValid)
{
newSong.Validate().AddToModelState(ModelState, null);
_logger.LogWarning("{method} failed model validation (ModelState: {@modelState}), returning Unprocessable Entity", nameof(Post), ModelState.Values.SelectMany(v => v.Errors));
return UnprocessableEntity(ModelState);
}
但是,这不会像内置验证那样触发InvalidModelStateResponseFactory
。
有谁知道我如何从我的 controller 中触发相同类型的事件来使用这个方便的处理程序?
事实上,有一个非常简单的答案。 通过使用这个 ValidationProblem 模式,您可以简单地返回ValidationProblem(ModelState)
,而不是返回Ok()
或BadRequest()
或诸如此类的ActionResult
,它将使用Startup.cs
Api 配置中的工厂设置!
所以这就是我可以做的:
if (!newSong.IsValid)
{
newSong.Validate().AddToModelState(ModelState, null);
_logger.LogWarning("{method} failed model validation (ModelState: {@modelState}), returning Unprocessable Entity", nameof(Post), ModelState.Values.SelectMany(v => v.Errors));
return ValidationProblem(ModelState);
}
此外,您需要像这样覆盖行为以将其从您的启动中拉出(感谢 Kevin Dockx 的这个想法):
public override ActionResult ValidationProblem([ActionResultObjectValue] ModelStateDictionary modelStateDictionary)
{
var options = HttpContext.RequestServices.GetRequiredService<IOptions<ApiBehaviorOptions>>();
return (ActionResult)options.Value.InvalidModelStateResponseFactory(ControllerContext);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.