抑制 ASP.NET Core 的自动 400 响应中的验证错误
Suppress validation errors in ASP.NET Core's automatic 400 response
虽然 automatic 400 response 很有用,但我不想向客户端发送验证错误。
这是响应正文:
{
"errors": {
"username": [
"'username' must not be empty."
],
...more errors
},
"title": "One or more validation errors occurred",
"status": 400,
"traceId": "xxx:yyy"
}
但我想要的是默认值,没有错误:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "Bad Request",
"status": 400,
"traceId": "xxx:yyy"
}
我以为我需要做的就是设置
options.SuppressUseValidationProblemDetailsForInvalidModelStateResponses = true;
...但这没有任何作用。
我不想禁用此功能,我只是想抑制验证错误。我该怎么做?
顺便说一句,我正在使用一种变通方法,通过手动创建响应主体,但我希望避免这种情况:
services.Configure<ApiBehaviorOptions>(apiBehaviorOptions => {
apiBehaviorOptions.InvalidModelStateResponseFactory = actionContext => {
var pd = new ProblemDetails();
pd.Type = apiBehaviorOptions.ClientErrorMapping[400].Link;
pd.Title = apiBehaviorOptions.ClientErrorMapping[400].Title;
pd.Status = 400;
pd.Extensions.Add("traceId", actionContext.HttpContext.TraceIdentifier);
return new BadRequestObjectResult(pd);
};
});
"Problem details"对应RFC 7807,是对HTTP API报错方式的标准化尝试。 SuppressUseValidationProblemDetailsForInvalidModelStateResponses
不具体涵盖实际验证错误的返回,仅涵盖 RFC 中讨论的标准位。
做你想做的事情的唯一方法就是你已经做过的事情,即使用自定义工厂。这不是 hack 或解决方法:这是更改自动响应的记录方式。
也就是说,抑制验证错误绝对没有意义。整个要点是通知客户请求中存在哪些错误,以便客户可以更正这些错误。没有它,您只是砰地关上门,没有任何指示出了什么问题或如何解决它。
ProblemDetails 的问题在于它是 StatusCodeResult 的默认响应,其 StatusCode 大于或等于 400。https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.statuscoderesult?view=aspnetcore-6.0
如果状态大于或等于 400,则以下操作会生成带有 ProblemDetails 的响应。
[HttpGet("raw/{status}")]
public IActionResult GetRawStatus(int status)
{
return StatusCode(status);
}
要取消默认的 ProblemDetails 响应正文,您可以使用带有状态的空 ObjectResult。
下面的示例为任何状态代码生成一个没有问题详细信息的响应。
[HttpGet("object/{status}")]
public IActionResult GetObjectStatus(int status)
{
return new ObjectResult(null) { StatusCode = status };
}
虽然 automatic 400 response 很有用,但我不想向客户端发送验证错误。
这是响应正文:
{
"errors": {
"username": [
"'username' must not be empty."
],
...more errors
},
"title": "One or more validation errors occurred",
"status": 400,
"traceId": "xxx:yyy"
}
但我想要的是默认值,没有错误:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "Bad Request",
"status": 400,
"traceId": "xxx:yyy"
}
我以为我需要做的就是设置
options.SuppressUseValidationProblemDetailsForInvalidModelStateResponses = true;
...但这没有任何作用。
我不想禁用此功能,我只是想抑制验证错误。我该怎么做?
顺便说一句,我正在使用一种变通方法,通过手动创建响应主体,但我希望避免这种情况:
services.Configure<ApiBehaviorOptions>(apiBehaviorOptions => {
apiBehaviorOptions.InvalidModelStateResponseFactory = actionContext => {
var pd = new ProblemDetails();
pd.Type = apiBehaviorOptions.ClientErrorMapping[400].Link;
pd.Title = apiBehaviorOptions.ClientErrorMapping[400].Title;
pd.Status = 400;
pd.Extensions.Add("traceId", actionContext.HttpContext.TraceIdentifier);
return new BadRequestObjectResult(pd);
};
});
"Problem details"对应RFC 7807,是对HTTP API报错方式的标准化尝试。 SuppressUseValidationProblemDetailsForInvalidModelStateResponses
不具体涵盖实际验证错误的返回,仅涵盖 RFC 中讨论的标准位。
做你想做的事情的唯一方法就是你已经做过的事情,即使用自定义工厂。这不是 hack 或解决方法:这是更改自动响应的记录方式。
也就是说,抑制验证错误绝对没有意义。整个要点是通知客户请求中存在哪些错误,以便客户可以更正这些错误。没有它,您只是砰地关上门,没有任何指示出了什么问题或如何解决它。
ProblemDetails 的问题在于它是 StatusCodeResult 的默认响应,其 StatusCode 大于或等于 400。https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.statuscoderesult?view=aspnetcore-6.0
如果状态大于或等于 400,则以下操作会生成带有 ProblemDetails 的响应。
[HttpGet("raw/{status}")]
public IActionResult GetRawStatus(int status)
{
return StatusCode(status);
}
要取消默认的 ProblemDetails 响应正文,您可以使用带有状态的空 ObjectResult。
下面的示例为任何状态代码生成一个没有问题详细信息的响应。
[HttpGet("object/{status}")]
public IActionResult GetObjectStatus(int status)
{
return new ObjectResult(null) { StatusCode = status };
}