OpenAPI wrong schema generation
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 290
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### Describe the bug
With .net 9, we had Type, Type2, Type3 generated in openapi definition (using Microsoft.Extensions.ApiDescription.Server) - that was buggy but at least tractable.
With .net 10, components are emitted using type name - and not using the type - leading to wrong types being generated if multiple types have same name (not-considering namespace) and __completely silently__.
### Expected Behavior
Components shall be all generated, deduplicated and eventually named with a numbering scheme as before in case of name conflicts.
### Steps To Reproduce
# OpenApiOneFile.csproj
````
net10.0
enable
enable
.
runtime; build; native; contentfiles; analyzers; buildtransitive
all
````
# Program.cs
````
namespace SampleApiOneFile.Models {
public record User {
public required int Id { get; init; }
public required string FirstName { get; init; }
public required string LastName { get; init; }
}
}
namespace SampleApiOneFile.Models.Patch {
public record User {
public string? FirstName { get; init; }
public string? LastName { get; init; }
}
}
namespace SampleApiOneFile.Controllers {
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("[controller]")]
public partial class UserController() : ControllerBase {
[HttpGet("{id}")]
public ActionResult Get(int id) {
return new Models.User {
Id = id,
FirstName = $"FirstName {id}",
LastName = $"LastName {id}"
};
}
[HttpPatch("{id}")]
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult Update(int id, Models.Patch.User patch) {
return new Models.User {
Id = id,
FirstName = patch.FirstName ?? $"FirstName {id}",
LastName = patch.LastName ?? $"LastName {id}"
};
}
}
}
namespace SampleApiOneFile {
public static class Program {
public static int Main(string[] args) {
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenApi();
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
return 0;
}
}
}
````
# Generated SampleApiOneFile.json (OpenAPI schema):
````
{
"openapi": "3.1.1",
"info": {
"title": "SampleApiOneFile | v1",
"version": "1.0.0"
},
"paths": {
"/User/{id}": {
"get": {
"tags": [
"User"
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"pattern": "^-?(?:0|[1-9]\\d*)$",
"type": [
"integer",
"string"
],
"format": "int32"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/User"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/User"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/User"
}
}
}
}
}
},
"patch": {
"tags": [
"User"
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"pattern": "^-?(?:0|[1-9]\\d*)$",
"type": [
"integer",
"string"
],
"format": "int32"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/User"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/User"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/User"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "OK",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/User"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/User"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/User"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"User": {
"type": "object",
"properties": {
"firstName": {
"type": [
"null",
"string"
]
},
"lastName": {
"type": [
"null",
"string"
]
}
}
}
}
},
"tags": [
{
"name": "User"
}
]
}
````
Look at User component definition: it's plain wrong. We shall have here 2 components:
- one for Models.User - with no nullable
- one for Models.Patch.User - with nullable
### Exceptions (if any)
_No response_
### .NET Version
10.0.100
### Anything else?
macOS 15.7.2
Contributor guide
Assessment
This issue has not been assessed yet.