OpenAPI: Context.GetOrCreateSchemaAsync used in IOpenApiDocumentTransformer doesnt resolve some references
- 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
Our application has some POCOs that are used over SignalR that we like to include in our openAPI specs so clients can use them, for most classes this isnt necessary because the POCOs are used in a controller so they are exported to the spec already.
To do this we added an attribute that is picked up on by an `IOpenApiDocumentTransformer` that adds the schema to the openAPI spec (`ExtraOpenApiSchemasDocumentTransformer` below).
We've run into an issue where we have two POCOs, `StartCheckinDto` and `StoreCheckinDto`, that both reference an enum `CheckinType`. The `StartCheckinDto` is used in a controller and correctly used a reference for the property it has that is of type `CheckinType`:
The `StoreCheckinDto`, which uses our attribute & document transformer to be included in the schema without being used in a controller, does not use a reference in the spec and instead re-declares the `CheckinType` enum:
I did come across [issue 63598](https://github.com/dotnet/aspnetcore/issues/63598) which seems related, but I'm not quite sure...
Inside of our `IOpenApiDocumentTransformer` I checked and the `x-schema-id` for both the `CheckinType` that is properly declared and referenced by `StartCheckinDto` and the one used while generating the `StoreCheckinDto` match and are both `"CheckinType"`
### Expected Behavior
Both `StartCheckinDto` and `StoreCheckinDto` should reference the same `CheckinType` in the spec
### Steps To Reproduce
Here are the various classes described above:
```
///
/// Adds any entities with the to the
/// OpenAPI Document if they are not present.
///
internal class ExtraOpenApiSchemasDocumentTransformer : IOpenApiDocumentTransformer
{
public async Task TransformAsync(
OpenApiDocument document,
OpenApiDocumentTransformerContext context,
CancellationToken cancellationToken
)
{
document.Components ??= new OpenApiComponents();
document.Components.Schemas ??= new Dictionary();
foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
{
if (type.GetCustomAttributes(typeof(IncludeInOpenApiSchemaAttribute), true).Length > 0)
{
if (!document.Components.Schemas.ContainsKey(type.Name))
{
var openApiSchema = await context.GetOrCreateSchemaAsync(
type,
null,
cancellationToken
);
document.Components.Schemas.Add(type.Name, openApiSchema);
}
}
}
}
}
public enum CheckinType
{
Shop,
Vend,
}
public class Checkin : BaseEntity
{
public required Guid StoreId { get; set; }
public required Guid CustomerId { get; set; }
public required CheckinType Type { get; set; }
}
public class StartCheckinDto
{
public required Guid CustomerId { get; set; }
public required CheckinType Type { get; set; }
}
[IncludeInOpenApiSchema]
public record StoreCheckinDto
{
public required Guid CheckinId { get; set; }
public required CheckinType CheckinType { get; set; }
public required Guid CustomerId { get; set; }
}
```
### Exceptions (if any)
_No response_
### .NET Version
10.0.103
### Anything else?
`Microsoft.AspNetCore.OpenApi` @ `10.0.9`
`Microsoft.OpenApi` @ `2.9.0`
Contributor guide
Assessment
This issue has not been assessed yet.