dotnet / dotnet/aspnetcore

Records, positional parameters, data annotations, model validation and OpenAPI inconsistency

Open
#57,486 6 comments 2 reactions 0 assignees View on GitHub
area-minimal area-mvc feature-openapi
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

### Is there an existing issue for this?

- [X] I have searched the existing issues

### Describe the bug

When creating a .NET 9 (Preview 7) WepAPI project through means of `dotnet new webapi -controllers`, the [new OpenAPI support](https://aka.ms/aspnet/openapi) is [added by default](https://github.com/CaringDev/PRDA/blob/main/Program.cs#L7).

Many developers have come to love [DataAnnotations](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations) for increasing the likelihood incoming data matches their expectations.

After adding a record such as `public record NormalNoOpenApi([StringLength(2)] string Payload);` and a controller method e.g. `public void Post(NormalNoOpenApi _)` the data is indeed validated. However, the relevant schema entry in the OpenAPI document is missing the length constraints `"maxLength": 2, "minLength": 0,`:
```json
"NormalNoOpenApi": {
"required": ["payload"],
"type": "object",
"properties": {
"payload": { "type": "string" }
}
}
```

On the other hand, changing the record to `public record NoValidation([property: StringLength(2)] string Payload);` will lead to the correct schema but throw at runtime:

> System.InvalidOperationException: Record type 'PRDA.NoValidation' has validation metadata defined on property 'Payload' that will be ignored.
> 'Payload' is a parameter in the record primary constructor and validation metadata must be associated with the constructor parameter.

Going the extra mile and changing the record again: `public record NoGood([property: StringLength(2)][param: StringLength(2)] string Payload);` does not help: the schema is correct but we get the same exception.

Only changing to 'normal' properties helps:

```csharp
public record Good
{
[StringLength(2)] public required string Payload { get; init; }
}
```

### Expected Behavior

The OpenAPI document should match the actual model validation behavior.

### Steps To Reproduce

see https://github.com/CaringDev/PRDA for more context

### Exceptions (if any)

> System.InvalidOperationException: Record type '' has validation metadata defined on property '' that will be ignored.
> '' is a parameter in the record primary constructor and validation metadata must be associated with the constructor parameter.

### .NET Version

9.0.100-preview.7.24407.12

### Anything else?

Microsoft.AspNetCore.OpenApi = 9.0.0-preview.7.24406.2

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.