Values of additionalProperties not transformed · Issue #59616 · dotnet/aspnetcore (original) (raw)
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
When an endpoint returns a type containing a Dictionary
containing another type, the schema of this last type is not processed by schema transformers (see the missing "a": "b"
in Bar2
below, causing a new schema to be created).
{ "schemas": { "Bar": { "type": "object", "properties": { "value": { "type": "integer", "format": "int32", "a": "b" } }, "a": "b" }, "Bar2": { "type": "object", "properties": { "value": { "type": "integer", "format": "int32" } } }, "Foo": { "type": "object", "properties": { "bar": { "$ref": "#/components/schemas/Bar" }, "bars": { "type": "object", "additionalProperties": { "$ref": "#/components/schemas/Bar2" }, "a": "b" } }, "a": "b" } } }
My guess is that additionalProperties
should be processed somewhere here:
private async Task InnerApplySchemaTransformersAsync(OpenApiSchema schema, |
---|
JsonTypeInfo jsonTypeInfo, |
JsonPropertyInfo? jsonPropertyInfo, |
OpenApiSchemaTransformerContext context, |
IOpenApiSchemaTransformer transformer, |
CancellationToken cancellationToken = default) |
{ |
context.UpdateJsonTypeInfo(jsonTypeInfo, jsonPropertyInfo); |
await transformer.TransformAsync(schema, context, cancellationToken); |
// Only apply transformers on polymorphic schemas where we can resolve the derived |
// types associated with the base type. |
if (schema.AnyOf is { Count: > 0 } && jsonTypeInfo.PolymorphismOptions is not null) |
{ |
var anyOfIndex = 0; |
foreach (var derivedType in jsonTypeInfo.PolymorphismOptions.DerivedTypes) |
{ |
var derivedJsonTypeInfo = _jsonSerializerOptions.GetTypeInfo(derivedType.DerivedType); |
if (schema.AnyOf.Count <= anyOfIndex) |
{ |
break; |
} |
await InnerApplySchemaTransformersAsync(schema.AnyOf[anyOfIndex], derivedJsonTypeInfo, null, context, transformer, cancellationToken); |
anyOfIndex++; |
} |
} |
if (schema.Items is not null) |
{ |
var elementTypeInfo = _jsonSerializerOptions.GetTypeInfo(jsonTypeInfo.ElementType!); |
await InnerApplySchemaTransformersAsync(schema.Items, elementTypeInfo, null, context, transformer, cancellationToken); |
} |
if (schema.Properties is { Count: > 0 }) |
{ |
foreach (var propertyInfo in jsonTypeInfo.Properties) |
{ |
if (schema.Properties.TryGetValue(propertyInfo.Name, out var propertySchema)) |
{ |
await InnerApplySchemaTransformersAsync(propertySchema, _jsonSerializerOptions.GetTypeInfo(propertyInfo.PropertyType), propertyInfo, context, transformer, cancellationToken); |
} |
} |
} |
} |
Expected Behavior
I expected to see
{ "schemas": { "Bar": { "type": "object", "properties": { "value": { "type": "integer", "format": "int32", "a": "b" } }, "a": "b" }, "Foo": { "type": "object", "properties": { "bar": { "$ref": "#/components/schemas/Bar" }, "bars": { "type": "object", "additionalProperties": { "$ref": "#/components/schemas/Bar" }, "a": "b" } }, "a": "b" } } }
Steps To Reproduce
Add a schema transformer like so:
options.AddSchemaTransformer((schema, _, _) => { schema.Extensions.Add("a", new OpenApiString("b")); return Task.CompletedTask; });
And add an endpoint that returns a type (Foo
) which contains a dictionary with another type (Bar
).
app.MapGet("/", () => new Foo());
class Foo { public Bar Bar { get; set; } public Dictionary<string, Bar> Bars { get; set; } }
class Bar { public int Value { get; set; } }
Exceptions (if any)
No response
.NET Version
9.0.200-preview.0.24575.35
Anything else?
No response