Непоследовательное поведение с валидацией ModelState asp.net core api - PullRequest
1 голос
/ 22 марта 2019

Я получаю несогласованное поведение, когда ядро ​​API asp.net проверяет объекты и когда я вручную добавляю ошибки модели и вызываю BadRequest (ModelState)

В качестве примера, у меня есть эти 2 конечные точки в моем контроллере

[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 или это известная проблема?

Ответы [ 3 ]

2 голосов
/ 22 марта 2019
  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;
    }
Или, если вам не нужен traceId, вы можете просто вернуть BadRequest из ValidationProblemDetails:
    ModelState.AddModelError("field", "error");
    var problemDetails = new ValidationProblemDetails(ModelState)
    {
        Status = StatusCodes.Status400BadRequest,
    };
    return BadRequest(problemDetails);

Демо:

enter image description here

Для получения дополнительной информации см. соответствующий исходный код здесь и здесь .

0 голосов
/ 14 мая 2019

Вы можете использовать

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

Этот код выдает аналогичный ответ, только без traceId.

0 голосов
/ 22 марта 2019

ApiController выполняет автоматическую проверку состояния модели и возвращает ответ в случае ошибки.

Если вам нужно подобное поведение, вы можете отключить автоматическую проверку и ответ:

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

См. Здесь для получения дополнительной информации. Надеюсь, это поможет!

...