dotnet / dotnet/aspnetcore

OpenApiSchema.AnyOf will reuse same key for schema

Open
#63,233 2 comments 0 reactions 0 assignees View on GitHub
area-minimal feature-openapi potentially-fixed
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

We want to create a OpenAPI schema like that:
```yaml
Response:
type: object
anyOf:
- type: object
properties:
optionalProperty:
type: integer
properties:
id:
type: integer
```
But we cannot add a value to OpenApiSchema.AnyOf, it will cause exception.

### Expected Behavior

_No response_

### Steps To Reproduce

```c#
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddOpenApi(x => x.AddSchemaTransformer());

var app = builder.Build();

app.MapOpenApi();
app.MapControllers();
app.Run();

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
[HttpGet]
public ResponseBody Get() => throw new NotImplementedException();
}

public class ResponseBody
{
public string Message { get; set; }
}

class Transformer : IOpenApiSchemaTransformer
{
public Task TransformAsync(
OpenApiSchema schema,
OpenApiSchemaTransformerContext context,
CancellationToken cancellationToken)
{
schema.AnyOf =
[
new OpenApiSchema
{
Type = "object",
Properties = new Dictionary { ["something"] = new() { Type = "string" } }
},
];

return Task.CompletedTask;
}
}
```

### Exceptions (if any)

`ArgumentException: An item with the same key has already been added. Key: ResponseBody `
```
System.Collections.Generic.Dictionary.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
System.Collections.Generic.Dictionary.Add(TKey key, TValue value)
Microsoft.AspNetCore.OpenApi.OpenApiSchemaReferenceTransformer.TransformAsync(OpenApiDocument document, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken)
Microsoft.AspNetCore.OpenApi.OpenApiDocumentService.ApplyTransformersAsync(OpenApiDocument document, IServiceProvider scopedServiceProvider, CancellationToken cancellationToken)
Microsoft.AspNetCore.OpenApi.OpenApiDocumentService.GetOpenApiDocumentAsync(IServiceProvider scopedServiceProvider, HttpRequest httpRequest, CancellationToken cancellationToken)
Microsoft.AspNetCore.OpenApi.OpenApiDocumentService.GetOpenApiDocumentAsync(IServiceProvider scopedServiceProvider, HttpRequest httpRequest, CancellationToken cancellationToken)
Microsoft.AspNetCore.Builder.OpenApiEndpointRouteBuilderExtensions+<>c__DisplayClass0_0+<b__0>d.MoveNext()
Microsoft.AspNetCore.Http.Generated.F56B68D2B55B5B7B373BA2E4796D897848BC0F04A969B1AF6260183E8B9E0BAF2__GeneratedRouteBuilderExtensionsCore+<>c__DisplayClass2_0+<g__RequestHandler|5>d.MoveNext()
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

```

### .NET Version

9.0.303

### Anything else?

Microsoft.AspNetCore.OponApi 9.0.8

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.