Calling BadRequest in controller is inconsistent with attribute validation
See original GitHub issueDescribe the bug
After upgrading to ASP.NET Core 2.2, I noticed that attribute-based model validation produces 400 response bodies like the following:
{
"errors": {
"Model.Field": [
"error message"
]
},
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|e43bcb39071100489dc1590f71370445.4fc1232b_"
}
I have some additional validation in my controller action based on a database lookup that looks something like this:
try
{
this.service.ServiceCall(model);
}
catch (InvalidModelException e)
{
this.ModelState.AddModelError(nameof(Model.Field), e.Message);
return this.BadRequest(this.ModelState);
}
The resulting response body looks like this:
{
"Model.Field": [
"error message"
]
}
Expected behavior
I would expect that calling ModelState.AddModelError
from a controller action, then passing ModelState
to BadRequest
would give a response body similar to that of attribute-based model validation.
Additional context
I noticed that calling
return this.BadRequest(new ValidationProblemDetails(this.ModelState));
gives a response body very close to the desired one, minus the traceId
field.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:12
- Comments:13 (5 by maintainers)
Top Results From Across the Web
Inconsistent behaviour with ModelState validation asp.net ...
I believe the framework might be calling AddModelError (string key, Exception exception, Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata ...
Read more >Extra Validation Errors In ASP.NET Core - Kevin Smith
When building APIs within ASP.NET Core, when we append the [ApiController] attribute to our controllers the framework does the heavy lifting of ...
Read more >Handle errors in ASP.NET Core web APIs
Using the preceding code, when an API controller returns BadRequest , an HTTP 400 response status is returned with no response body.
Read more >Handling errors in ASP.NET Core Web API - DevTrends
Handling errors in an ASP.NET Core Web API. This post looks at the best ways to handle exceptions, validation and other invalid requests...
Read more >Centralized exception handling and request validation in ...
Let's start with exception handling. ASP.NET Core exposes a feature called IExceptionHandlerFeature which you can use to globally handle ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@durgeshkumar14 There’s no out-of-the-box option to turn it off.
For regular client error mapping, you need to provide your own implementation of
IClientErrorFactory
. It’s probably best to just use the default as a starting point:https://github.com/aspnet/AspNetCore/blob/09b50850bc428119ea5adfdbceb0470b7a5c2546/src/Mvc/src/Microsoft.AspNetCore.Mvc.Core/Infrastructure/ProblemDetailsClientErrorFactory.cs#L10-L53
And leave out the call to
SetTraceId
. Add it like this:For validation errors, MVC uses the
ApiBehaviorOptions.InvalidModelStateResponseFactory
option to convert the validation errors into a result. The default implementation looks like this:https://github.com/aspnet/AspNetCore/blob/708dc5cb5abd1fe0aa409f355b9e0cea8f6846d4/src/Mvc/src/Microsoft.AspNetCore.Mvc.Core/DependencyInjection/ApiBehaviorOptionsSetup.cs#L106-L121
You can set it by doing something like this:
It’s part of the extension data. See
ProblemDetailsClientErrorFactory.SetTraceId
😉