使用ModelState验证asp.net core api时的行为不一致

问题描述 投票:1回答:3

当asp.net核心api验证对象时以及当我手动添加模型错误并调用BadRequest(ModelState)时,我得到一个不一致的行为

举个例子,我在控制器中有这两个端点

[HttpPost]
public IActionResult Post(MyModel model)
{
    return Ok();
}

[HttpPost]
[Route("test")]
public IActionResult OtherPost()
{
    ModelState.AddModelError("field", "error");
    return BadRequest(ModelState);
}

和MyModel是:

public class MyModel
{
    [Required]
    [MinLength(10)]
    public string MyProperty { get; set; }
}

当我使用空体调用第一个端点时,我不需要验证ModelState,因为框架将自动执行并提供此响应:

{
"errors":{"MyProperty":["The MyProperty field is required."]},
"title":"One or more validation errors occurred.",
"status":400,
"traceId":"80000005-0000-ff00-b63f-84710c7967bb"
}

使用第二个控制器,我得到了这个:

{"field":["error"]}

我使用错误的方法向ModelState添加错误还是已知问题?

api asp.net-core bad-request
3个回答
2
投票
  1. 如果您希望自己验证模型状态并期望与ApiController绑定的失败消息完全相同的结果,您可以按如下方式进行:
    public IActionResult Other2Post()
    {
        ModelState.AddModelError("field", "error");
        var problemDetails = new ValidationProblemDetails(ModelState)
        {
            Status = StatusCodes.Status400BadRequest,
        };

        var traceId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
        problemDetails.Extensions["traceId"] = traceId;

        var result = new BadRequestObjectResult(problemDetails);
        result.ContentTypes.Add("application/problem+json");
        result.ContentTypes.Add("application/problem+xml");
        return result;
    }
  1. 或者,如果你不需要traceId,你可以简单地返回BadRequestValidationProblemDetails
    ModelState.AddModelError("field", "error");
    var problemDetails = new ValidationProblemDetails(ModelState)
    {
        Status = StatusCodes.Status400BadRequest,
    };
    return BadRequest(problemDetails);

演示:

enter image description here

有关更多信息,请参阅the related source code herehere


1
投票

你可以用

public IActionResult Post(SomeModel model)
{
    ModelState.AddModelError("key", "message");
    return ValidationProblem(ModelState);
}

此代码产生类似的响应,仅使用traceId。


0
投票

ApiController执行自动模型状态验证,并在发生错误时返回响应。

如果您想要类似的行为,可以禁用自动验证和响应:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<ApiBehaviorOptions>(options =>
    {
        options.SuppressModelStateInvalidFilter = true;
    });
}

See here了解更多信息。希望能帮助到你!

© www.soinside.com 2019 - 2024. All rights reserved.