aspnetcore: .NET 7 Preview 7 ProblemDetailsService is not working as expected.

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

The release note says that:

.NET 7 Preview 7 introduces a new problem details service based on the IProblemDetailsService interface for generating consistent problem details responses in your app.

To add the problem details service, use the AddProblemDetails extension method on IServiceCollection.

builder.Services.AddProblemDetails();

I have done so. Now I have the following endpoint:

[HttpPost]
public ActionResult Post(CreateWFModel model)
{
    if (model.Summary?.Length < 100)
    {
        ModelState.AddModelError("Summary", "The summary should be at least 100 characters.");
        return BadRequest(ModelState);
    }

    return Ok();
}

public class CreateWFModel
{
    public DateTime Date { get; set; }

    public int TemperatureC { get; set; }

    [Required]
    public string? Summary { get; set; }
}

Now if I don’t provide the value of the summary then the response shows as follows:

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "00-2759a2ba3ce779e64e8ec4f21e4565fc-7b9e6059c062c576-00",
  "errors": {
    "Summary": [
      "The Summary field is required."
    ]
  }
}

This is fine!

But when I provide less than 100 chars, the response shows as follows:

{
  "Summary": [
    "The summary should be at least 100 characters."
  ]
}

Which is totally inconsistent. I want the response should be:

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "00-2759a2ba3ce779e64e8ec4f21e4565fc-7b9e6059c062c576-00",
  "errors": {
    "Summary": [
       "The summary should be at least 100 characters."
    ]
  }
}

I have also tried the following but the result is the same:

public class CustomWriter : IProblemDetailsWriter
{
    // Indicates that only responses with StatusCode == 400
    // will be handled by this writer. All others will be
    // handled by different registered writers if available.
    public bool CanWrite(ProblemDetailsContext context) 
        => context.HttpContext.Response.StatusCode == 400;

    public ValueTask WriteAsync(ProblemDetailsContext context)
    {
        //Additional customizations

        // Write to the response
        context.HttpContext.Response.WriteAsJsonAsync(context.ProblemDetails);
       return ValueTask.CompletedTask;
    }        
}

builder.Services.AddSingleton<IProblemDetailsWriter, CustomWriter>();
builder.Services.AddProblemDetails();

.NET Version

.NET 7.0 Preview 7

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 30 (24 by maintainers)

Most upvoted comments

@Rick-Anderson maybe we could add something about it in the docs if not there yet.

See #29152

@brunolins16 thanks for checking! I created a simple web app here that illustrates the problem:

https://github.com/jchoca/ProblemDetailsJsonSettings

if you hit the root endpoint it returns pascal case, but if you hit /error it returns camel case.

Hi, I think this may be related, but the casing for ProblemDetails is also inconsistent. ProblemDetails itself defaults to camel case, but as you can see above when describing the “Summary” field, it’s capitalized. Shouldn’t that be lower case, assuming @TanvirArjel is using the default naming policy?

In MVC for scenarios where the Validation Problem Details is auto generated, by default, it does not change it unless (.NET 7 only) you:

  1. Adds SystemTextJsonValidationMetadataProvider (https://github.com/dotnet/aspnetcore/issues/39010) (recommended)
services..AddControllers(options => options.ModelMetadataDetailsProviders.Add(new SystemTextJsonValidationMetadataProvider()))
  1. Set JsonSerializerOptions.DictionaryKeyPolicy (https://github.com/dotnet/aspnetcore/pull/38853)
services.AddControllers().AddJsonOptions(options => 
{ 
    options.JsonSerializerOptions.DictionaryKeyPolicy = System.Text.Json.JsonNamingPolicy.CamelCase;
});

We have plans to make the provider default for ApiControllers, but it will only come for .NET 8 (https://github.com/dotnet/aspnetcore/issues/40408)

@brunolins16 Wish you all the very best for dotNET 8.0 😃 But please don’t miss this.