为什么自动模型状态返回400状态码而不是422?

3
我有一段使用数据注释进行验证的代码。
[Route("api/[controller]")]
[ApiController]
public class AccountController : ControllerBase
{
    private readonly IAccountService _accountService;


    /// <param name="accountService"></param>
    public AccountController(IAccountService accountService)
    {
        _accountService = accountService;
    }

    [HttpGet]
    [Route("IsAccountClosed/{nric}")]
    public async Task<ActionResult> IsAccountClosed([Required] string nric)
    {
      // code removed for brevity
    }
}

当我传递一个空字符串(带一个空格)进行测试时,它会返回400状态码。下面是在Swagger中的输出。

enter image description here

我的问题是为什么默认情况下它返回400状态码而不是更准确的422状态码?如何在内容类型仍为application/problem+json的情况下将其更改为422状态码?
应用Yong Shun的建议后,我可以得到422状态码和内容类型为application/problem+json,但响应体与以下所示不同。

enter image description here


1
你好,我想澄清一下,你是在使用.NET框架还是.NET Core或以上版本来构建Web API呢? - Yong Shun
Net Core .Net 6 - Steve
1
由于ASP.NET团队感到困惑,您需要按照下面的答案手动设置无效响应生成工厂。 - Tanveer Badar
1个回答

4

更新

经过一些研究和试错,这是InvalidModelStateResponseFactory生成状态码为400的响应的方式。

对于您的情况,您只需要重写statusCode但保留响应结构。

要实现:

  1. 获取 ProblemDetailsFactory 服务。

  2. 通过提供当前 HttpContext、ModelState 和422状态码(如果没有此步骤,则响应体中的status将默认为400)创建 ValidationProblemDetails (这是无效模型状态响应体的结构)。

  3. 最后,创建 BadRequestObjectResult 并提供状态码为422。

builder.Services.AddControllers()
    .ConfigureApiBehaviorOptions(options =>
        options.InvalidModelStateResponseFactory = context =>
        {
            var problemDetailsFactory = context.HttpContext.RequestServices.GetRequiredService<ProblemDetailsFactory>();
            ValidationProblemDetails problemDetails = problemDetailsFactory.CreateValidationProblemDetails(context.HttpContext, context.ModelState, 422);

            return new ObjectResult(problemDetails)
            {
                StatusCode = 422
            };
        }
    );

enter image description here


现在它返回为422,但其响应内容类型变为application/json而不是application/problem+json - Steve
1
没有测试代码,但我认为你可以尝试使用 new UnprocessableEntityObjectResult(context.ModelState) { ContentTypes = { "application/problem+json" } } 设置内容类型。 - Yong Shun
现在它的内容类型是“application/problem+json”,但响应体与预期不同。我更新了我的帖子以显示响应体。 - Steve
1
嗨,抱歉,我更新了我的答案。谢谢。 - Yong Shun
1
很酷,它按预期工作。谢谢@Yong Shun - Steve

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接