-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Fix mapping for nested schemas and [Produces] attributes in OpenAPI implementation #57852
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,8 @@ namespace Microsoft.AspNetCore.OpenApi; | |
| /// </summary> | ||
| internal sealed class OpenApiSchemaStore | ||
| { | ||
| // Matches default MaxValidationDepth and MaxModelBindingRecursionDepth used by MVC. | ||
| private readonly int MaxSchemaReferenceRecursionDepth = 32; | ||
| private readonly Dictionary<OpenApiSchemaKey, JsonNode> _schemas = new() | ||
| { | ||
| // Pre-populate OpenAPI schemas for well-defined types in ASP.NET Core. | ||
|
|
@@ -79,32 +81,37 @@ public JsonNode GetOrAdd(OpenApiSchemaKey key, Func<OpenApiSchemaKey, JsonNode> | |
| /// </summary> | ||
| /// <param name="schema">The <see cref="OpenApiSchema"/> to add to the schemas-with-references cache.</param> | ||
| /// <param name="captureSchemaByRef"><see langword="true"/> if schema should always be referenced instead of inlined.</param> | ||
| public void PopulateSchemaIntoReferenceCache(OpenApiSchema schema, bool captureSchemaByRef) | ||
| /// <param name="currentDepth">The current recursion depth for the reference schema.</param> | ||
| public void PopulateSchemaIntoReferenceCache(OpenApiSchema schema, bool captureSchemaByRef, int currentDepth = 0) | ||
| { | ||
| // Only capture top-level schemas by ref. Nested schemas will follow the | ||
| // reference by duplicate rules. | ||
| if (schema == null || currentDepth > MaxSchemaReferenceRecursionDepth) | ||
| { | ||
| return; | ||
|
||
| } | ||
|
|
||
| AddOrUpdateSchemaByReference(schema, captureSchemaByRef: captureSchemaByRef); | ||
| AddOrUpdateAnyOfSubSchemaByReference(schema); | ||
|
|
||
| if (schema.AdditionalProperties is not null) | ||
| { | ||
| AddOrUpdateSchemaByReference(schema.AdditionalProperties); | ||
| PopulateSchemaIntoReferenceCache(schema.AdditionalProperties, captureSchemaByRef, currentDepth++); | ||
| } | ||
| if (schema.Items is not null) | ||
| { | ||
| AddOrUpdateSchemaByReference(schema.Items); | ||
| PopulateSchemaIntoReferenceCache(schema.Items, captureSchemaByRef, currentDepth++); | ||
| } | ||
| if (schema.AllOf is not null) | ||
| { | ||
| foreach (var allOfSchema in schema.AllOf) | ||
| { | ||
| AddOrUpdateSchemaByReference(allOfSchema); | ||
| PopulateSchemaIntoReferenceCache(allOfSchema, captureSchemaByRef, currentDepth++); | ||
| } | ||
| } | ||
| if (schema.Properties is not null) | ||
| { | ||
| foreach (var property in schema.Properties.Values) | ||
| { | ||
| AddOrUpdateSchemaByReference(property); | ||
| PopulateSchemaIntoReferenceCache(property, captureSchemaByRef, currentDepth++); | ||
| } | ||
| } | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MaxValidationDepthandMaxModelBindingRecursionDepthare both configurable viaMvcOptions. Do we think this will need to be configurable too?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a future release, yes, but we will have to live with it being un-configurable for .NET 9 for now. :/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per off-line discussion, we're relying on STJ's recursion depth check which do have a configurable option via
JsonSerializerOptions.MaxDepth.