Skip to content

Respect JsonSerializerOptions casing for property names in validation errors #61764

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
captainsafia opened this issue May 1, 2025 · 0 comments · May be fixed by #62036
Open

Respect JsonSerializerOptions casing for property names in validation errors #61764

captainsafia opened this issue May 1, 2025 · 0 comments · May be fixed by #62036
Assignees
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc feature-validation Issues related to model validation in minimal and controller-based APIs

Comments

@captainsafia
Copy link
Member

captainsafia commented May 1, 2025

HttpValidationProblemDetails (returned by TypedResults.ValidationProblem, BadRequest(ModelState) and the automatic minimal-API parameter validation pipeline) currently reports member names exactly as they appear in CLR code (PascalCase). When an app opts into a different JSON naming policy—most commonly camelCase via

builder.Services.ConfigureHttpJsonOptions(o =>
    o.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase);

the payload that describes the validation failure no longer matches the property names clients actually send or expect to receive. This breaks tooling that relies on the error object for UI-binding or automatic form generation and is inconsistent with other framework-generated JSON (OpenAPI, regular serialization, etc.). 

The root cause is that the code paths in src/Http/Http.Abstractions/src/Validation choose ValidationResult.MemberName from reflection data (PropertyInfo.Name) without running it through the serializer’s PropertyNamingPolicy.

Reproduction

using System.ComponentModel.DataAnnotations;
using System.Text.Json;
var builder = WebApplication.CreateBuilder(args);

builder.Services.ConfigureHttpJsonOptions(o =>
    o.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase);

var app = builder.Build();

app.MapPost("/people", (Person p) => Results.Ok(p));

app.Run();

record Person([Required] string FirstName, [Required] string LastName);

Request

POST /people
Content-Type: application/json

{ "firstName": "Ada" }     //  lastName is missing

Current output

{
  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.41",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "errors": {
    "LastName": [
      "The LastName field is required."
    ]
  }
}

Notice the PascalCase LastName.

Expected output

{
  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.41",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "errors": {
    "lastName": [
      "The lastName field is required."
    ]
  }
}

The member name should respect the configured naming policy or any [JsonPropertyName] attribute.

The fix for this should include:

Because the validation helpers live entirely in Http.Abstractions, the change is self-contained and should not affect MVC's codepaths.

@ghost ghost added the area-blazor Includes: Blazor, Razor Components label May 1, 2025
@captainsafia captainsafia added feature-validation Issues related to model validation in minimal and controller-based APIs area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc and removed area-blazor Includes: Blazor, Razor Components labels May 1, 2025
@captainsafia captainsafia assigned Copilot and unassigned Copilot May 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc feature-validation Issues related to model validation in minimal and controller-based APIs
Projects
None yet
1 participant