dotnet / dotnet/aspnetcore

Respect JsonSerializerOptions casing for property names in validation errors

Open
#61,764 3 comments 3 reactions 1 assignee Assigned to @Copilot View on GitHub
area-minimal feature-validation
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

## Background and Motivation

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

```csharp
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

```csharp
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:
- Support for resolving the configured JsonOptions from the ServiceProvider on the ValidationContext when inserting errors into the ValidateContext
- New tests in https://github.com/dotnet/aspnetcore/blob/main/src/Http/Http.Abstractions/test/Validation/ValidatableTypeInfoTests.cs that validate the behavior of the result with the custom JSON options

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

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.