OpenAPI: Incorrect ref is generated for a nested array field when returning collection of JsonPolymorphic types from a controller
- 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
There is a scenario when incorrect (empty) ref is generated.
As far as I can tell, it happens when controller returns a collection of JsonPolymorphic types which have nested array field. While OpenAPI is not supposed to be attempting optimizing default types, it tries to extract it into schema and fails.
Instead, `"$ref": "#/components/schemas//items/anyOf/0/properties//properties/"` ref is created
### Expected Behavior
Correct schema is generated for the array field
### Steps To Reproduce
TestController.cs:
```using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Mvc;
namespace OpenAPIBug.Controllers;
public class Embedded
{
public string[] Shared { get; set; } = [];
}
[JsonPolymorphic(UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)]
[JsonDerivedType(typeof(Derived1), typeDiscriminator: "Derived1")]
public class TestBase
{
public Embedded Embedded { get; set; } = new();
}
public class Derived1 : TestBase
{
}
[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
[HttpGet(Name = "GetTest")]
[ProducesResponseType(200, contentType: "application/json")]
public async Task> Get()
{
TestBase[] result = new[]
{
new TestBase()
};
return Ok(result);
}
}
```
Project.csproj:
```
net10.0
enable
enable
all
runtime; build; native; contentfiles; analyzers; buildtransitive
```
Program.cs:
```
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
```
Result:
```
{
"openapi": "3.1.1",
"info": {
"title": "OpenAPIBug | v1",
"version": "1.0.0"
},
"paths": {
"/Test": {
"get": {
"tags": [
"Test"
],
"operationId": "GetTest",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/TestBase"
}
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Embedded": {
"type": "object",
"properties": {
"shared": {
"$ref": "#/components/schemas//items/anyOf/0/properties/embedded/properties/shared"
}
}
},
"TestBase": {
"type": "object",
"anyOf": [
{
"$ref": "#/components/schemas/TestBaseDerived1"
},
{
"$ref": "#/components/schemas/TestBaseBase"
}
]
},
"TestBaseBase": {
"properties": {
"embedded": {
"$ref": "#/components/schemas/Embedded"
}
}
},
"TestBaseDerived1": {
"required": [
"$type"
],
"properties": {
"$type": {
"enum": [
"Derived1"
],
"type": "string"
},
"embedded": {
"$ref": "#/components/schemas/Embedded"
}
}
}
}
},
"tags": [
{
"name": "Test"
}
]
}
```
### Exceptions (if any)
_No response_
### .NET Version
10.0.101
### Anything else?
Might be related to https://github.com/dotnet/aspnetcore/issues/64193, but might be a separate issue because of JsonPolymorphic
Contributor guide
Research direction
The reproduction is defined in TestController.cs, with OpenAPI registered and mapped in Program.cs. First run the sample and inspect the generated document, then trace the schema handling for the polymorphic TestBase[] response and nested Embedded.Shared array. Done means the generated schema contains a valid reference for the array field instead of an empty path.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, openapi
- Domain
- api
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100