question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Calling BadRequest in controller is inconsistent with attribute validation

See original GitHub issue

Describe 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:closed
  • Created 5 years ago
  • Reactions:12
  • Comments:13 (5 by maintainers)

github_iconTop GitHub Comments

3reactions
khellangcommented, Jan 15, 2019

@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:

services.TryAddSingleton<IClientErrorFactory, MyCustomProblemDetailsClientErrorFactory>();

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:

services.Configure<ApiBehaviorOptions>(options =>
{
    options.InvalidModelStateResponseFactory = context =>
    {
        var problemDetails = new ValidationProblemDetails(context.ModelState);

        var result = new BadRequestObjectResult(problemDetails); 

        result.ContentTypes.Add("application/problem+json"); 
        result.ContentTypes.Add("application/problem+xml"); 
  
        return result;
    };
});
2reactions
khellangcommented, Jun 14, 2019

It’s part of the extension data. See ProblemDetailsClientErrorFactory.SetTraceId 😉

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found