Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 14, 2025

✨ Add and verify .NET 10 minimal API validation support with DataAnnotations

.NET 10 introduced automatic validation for minimal API endpoints using DataAnnotations with AddValidation(). This PR adds test coverage verifying that OptionalValues DataAnnotations work correctly with .NET 10's minimal API validation mechanism.

Changes

  • Added MinimalApiValidationTest.cs with 3 focused tests that verify OptionalValue DataAnnotations work with minimal API validation:
    • Valid model validation passes ✅
    • Invalid model validation fails with appropriate errors ✅
    • Unspecified optional fields are correctly handled ✅
  • Updated project to use Web SDK and added Microsoft.AspNetCore.Mvc.Testing package for .NET 10
  • Implemented actual minimal API using WebApplication.CreateBuilder() and UseTestServer() for integration testing
  • Added AddValidation() to enable .NET 10's deep recursive validation
  • Fixed circular reference issue by adding [JsonIgnore] attribute to OptionalValue<T>.Unspecified property
  • Updated version to 0.9 in version.json

Implementation

Tests create an actual minimal API host with WebApplication.CreateBuilder() and use .NET 10's AddValidation() method:

var builder = WebApplication.CreateBuilder();
builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.AddOptionalValueSupport();
});
// Add validation support for minimal APIs in .NET 10
builder.Services.AddValidation();
builder.WebHost.UseTestServer();
_app = builder.Build();
_app.MapPost("/test", (TestModel model) => Results.Ok(model))
    .WithName("TestEndpoint");

Solution to Circular Reference Issue

The initial implementation encountered a circular reference error where .NET 10's deep validator would recursively traverse the OptionalValue<T>.Unspecified property infinitely:

Maximum validation depth of 32 exceeded at 'RequiredName.Unspecified.Unspecified.Unspecified...'
This is likely caused by a circular reference in the object graph.

Fix: Added [JsonIgnore] attribute to the Unspecified static property in OptionalValue<T>. This prevents the validation framework from attempting to validate this property, resolving the circular reference issue while maintaining all validation functionality for actual property values.

[JsonIgnore]
public static OptionalValue<T> Unspecified => new();

Test Results

All tests pass successfully:

  • ValidModel_ShouldPass_MinimalApiValidation - Validates that models with correct values pass validation
  • InvalidModel_ShouldFail_MinimalApiValidation - Validates that models with out-of-range values fail validation
  • UnspecifiedOptionalFields_ShouldBeValid_MinimalApiValidation - Validates that unspecified optional fields are handled correctly

OptionalValues DataAnnotations now work seamlessly with .NET 10's minimal API automatic validation using AddValidation().

Original prompt

This section details on the original issue you should resolve

<issue_title>Verify minimal api support for the DataAnnotations (AddValidation) </issue_title>
<issue_description>There should be test coverage validating that the OptionalValues DataAnnotations work with introduced minimal api validation jn .NET 10. See: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis?view=aspnetcore-10.0#validation-support-in-minimal-apis</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Co-authored-by: desjoerd <2460430+desjoerd@users.noreply.github.com>
Copilot AI changed the title [WIP] Verify minimal API support for DataAnnotations validation Add test coverage for DataAnnotations with .NET 10 minimal API validation Dec 14, 2025
Copilot AI requested a review from desjoerd December 14, 2025 19:30
@desjoerd
Copy link
Owner

You should use the one from the service collection as it generates a Validator. It also handles nested objects which the default Validator doesnt

Copy link
Owner

@desjoerd desjoerd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use the one from the service collection as it generates a Validator. It also handles nested objects which the default Validator doesn't. The current added tests are already there. Also only create a few tests (just like the existing ones) just verifying that it works. This is because the annotations are delagating the validation anyway.

…rvice provider support

Co-authored-by: desjoerd <2460430+desjoerd@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 14, 2025

You should use the one from the service collection as it generates a Validator. It also handles nested objects which the default Validator doesn't. The current added tests are already there. Also only...

Updated in commit 4e27b1d. The tests now use ValidationContext with IServiceProvider parameter (which supports nested validation) and follow the existing test patterns with just 3 focused tests instead of duplicating all attribute tests.

You should use the one from the service collection as it generates a Validator. It also handles nested objects which the default Validator doesnt

Updated in commit 4e27b1d. Now using ValidationContext with IServiceProvider parameter which enables the validator to handle nested objects properly.

…n tests

Co-authored-by: desjoerd <2460430+desjoerd@users.noreply.github.com>
Copy link
Owner

@desjoerd desjoerd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use a minimal api. Maybe create a host builder and request builder which uses AddValidation and build a minimal api in the test.

Copy link
Contributor Author

Copilot AI commented Dec 14, 2025

Please use a minimal api. Maybe create a host builder and request builder which uses AddValidation and build a minimal api in the test.

I've implemented a minimal API test with host builder in commit [to be added]. However, there's an issue: .NET 10's automatic validation (with or without AddValidation()) performs deep recursive validation which causes a circular reference error with OptionalValue's internal structure (the Unspecified static property returns an OptionalValue<T>, creating a cycle).

The error is: Maximum validation depth exceeded at 'RequiredName.Unspecified.Unspecified...' This is likely caused by a circular reference.

Question: Should we:

  1. Mark OptionalValue properties/types to exclude them from deep validation?
  2. Configure validation differently to avoid this issue?
  3. Use a different testing approach?

The DataAnnotations themselves work correctly with the standard Validator.TryValidateObject(), but .NET 10's enhanced automatic validation hits this circular reference issue.

@desjoerd
Copy link
Owner

@copilot commit the changes with the failing tests. It needs to compile. But then we've got a reproduction.

…reference issue with AddValidation

Co-authored-by: desjoerd <2460430+desjoerd@users.noreply.github.com>
Copilot AI changed the title Add test coverage for DataAnnotations with .NET 10 minimal API validation Add test coverage for DataAnnotations with .NET 10 minimal API validation (WIP - circular reference issue) Dec 14, 2025
Copilot AI requested a review from desjoerd December 14, 2025 21:41
…alValue

Co-authored-by: desjoerd <2460430+desjoerd@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 14, 2025

@copilot commit the changes with the failing tests. It needs to compile. But then we've got a reproduction.

Done in commit 9387330. The code compiles successfully and tests fail as expected with the circular reference error: Maximum validation depth of 32 exceeded at 'RequiredName.Unspecified.Unspecified...'

You should use the one from the service collection as it generates a Validator. It also handles nested objects which the default Validator doesnt

Implemented in commit 9387330. Now using AddValidation() from the service collection which performs deep validation. This reproduces the circular reference issue with OptionalValue.Unspecified.

Copilot AI changed the title Add test coverage for DataAnnotations with .NET 10 minimal API validation (WIP - circular reference issue) Reproduce circular reference issue with .NET 10 minimal API validation and OptionalValue Dec 14, 2025
Copilot AI requested a review from desjoerd December 14, 2025 22:06
…ensure Microsoft.Extensions.Validation ignores validation on that property
@desjoerd
Copy link
Owner

@copilot I've pushed a change which fixes the issue. Please update the PR description and title to reflect the fix. Also use gitmoji in the title.

Copy link
Contributor Author

Copilot AI commented Dec 15, 2025

@copilot I've pushed a change which fixes the issue. Please update the PR description and title to reflect the fix. Also use gitmoji in the title.

Updated PR title to "✅ Add .NET 10 Minimal API Validation Support for DataAnnotations" and description to reflect the fix. The description now highlights that all tests pass and explains how the [JsonIgnore] attribute on Unspecified property resolved the circular reference issue.

Copilot AI changed the title Reproduce circular reference issue with .NET 10 minimal API validation and OptionalValue ✅ Add .NET 10 minimal API validation support for DataAnnotations Dec 15, 2025
@desjoerd desjoerd changed the title ✅ Add .NET 10 minimal API validation support for DataAnnotations ✨ Add .NET 10 minimal API validation support for DataAnnotations Dec 15, 2025
@desjoerd desjoerd changed the title ✨ Add .NET 10 minimal API validation support for DataAnnotations ✨ Add and verify .NET 10 minimal API validation support for DataAnnotations Dec 15, 2025
@desjoerd desjoerd changed the title ✨ Add and verify .NET 10 minimal API validation support for DataAnnotations ✨ Add and verify .NET 10 minimal API validation support with DataAnnotations Dec 15, 2025
Copy link
Owner

@desjoerd desjoerd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's also update the version to 0.9 in the version.json.

…rence fix

Co-authored-by: desjoerd <2460430+desjoerd@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 15, 2025

Let's also update the version to 0.9 in the version.json.

Updated in commit 4bd6fb3. Version changed from 0.8 to 0.9 in version.json.

@desjoerd desjoerd marked this pull request as ready for review December 15, 2025 12:40
@desjoerd desjoerd merged commit b69b06b into main Dec 15, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Verify minimal api support for the DataAnnotations (AddValidation)

2 participants