Inconsistent behaviour with ModelState validation asp.net core api

ApiController performs automatic model state validation and returns a response in case of an error.

If you want similar behavior, you can disable the automatic validation and response:

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

See here for more info. Hope it helps!


You could use

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

This code produces similar response, without traceId only.
UPD1: For asp.net core 3.1 it returns traceId


  1. If you prefer to validating the model state by yourself and expect a exactly same result as the failure message of ApiController binding, you could make it as below :
    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. Or if you don't need the traceId, you could simply return a BadRequest of ValidationProblemDetails:
    ModelState.AddModelError("field", "error");
    var problemDetails = new ValidationProblemDetails(ModelState)
    {
        Status = StatusCodes.Status400BadRequest,
    };
    return BadRequest(problemDetails);

Demo :

enter image description here

For more information, see the related source code here and here.