Support nullable array element types in parameter schemas - #68250
Support nullable array element types in parameter schemas#68250snemeckayova wants to merge 5 commits into
Conversation
62dcb7d to
1684f4d
Compare
There was a problem hiding this comment.
Pull request overview
Improves OpenAPI schema generation for minimal API parameters declared as nullable reference-type arrays (e.g., string?[]), ensuring the generated parameter schema correctly represents nullable array items by using NullabilityInfo.ElementType from ParameterInfo.
Changes:
- Updates parameter schema generation to detect nullable array element annotations via
NullabilityInfoContext. - Adds
MakeArrayItemsNullableto mark array item schemas nullable, wrapping referenced component item schemas inoneOfto avoid mutating shared components. - Updates the parameter schema tests to expect nullable items for
string?[].
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/OpenApi/test/Microsoft.AspNetCore.OpenApi.Tests/Services/OpenApiSchemaService/OpenApiSchemaService.ParameterSchemas.cs | Updates expectations so string?[] produces nullable array item schemas. |
| src/OpenApi/src/Services/OpenApiDocumentService.cs | Reuses a computed parameter schema and applies nullable-array-item adjustment when applicable. |
| src/OpenApi/src/Extensions/TypeExtensions.cs | Adds detection for nullable array element annotations via ParameterInfo nullability metadata. |
| src/OpenApi/src/Extensions/OpenApiSchemaExtensions.cs | Adds logic to mark array items nullable, using inline type-flagging or oneOf wrapping for referenced item schemas. |
Suppressed comments (1)
src/OpenApi/src/Extensions/OpenApiSchemaExtensions.cs:46
- The
elsebranch (wrappingItemsinoneOfto avoid mutating referenced component schemas) isn’t covered by the updated tests. Without coverage, it’s easy to regress behavior for array parameters whose element schema is componentized (e.g.,SomePoco?[]whereSomePocois emitted as a#/components/schemas/*reference). Please add a test that asserts the item schema becomes aoneOf: [null, $ref]wrapper and that the underlying component schema remains non-nullable.
public static bool IsComponentizedSchema(this OpenApiSchema schema, [NotNullWhen(true)] out string? schemaId)
{
if(schema.Metadata is not null
Youssef1313
left a comment
There was a problem hiding this comment.
- If we don't have an integration test for that already, could we add one?
- Can we ensure to have a test where an API has two parameters, one is
Model?[]and the second isModel[]? The goal is to ensure if both are componentized, we still get the correct nullability.
Youssef1313
left a comment
There was a problem hiding this comment.
When adding integration tests, let's also make sure we have a test for this when it's part of the API response
| // affect the shared componentized schema referenced by the other array parameter. | ||
| schemas.MapGet("/nullable-and-non-nullable-array-elements", (TestEnum?[] nullableValues, TestEnum[] values) => { }); | ||
| // Ensures the same componentized element type is reported correctly in a response. | ||
| schemas.MapGet("/complex-nullable-hierarchy", () => TypedResults.Ok(new ComplexHierarchyModel |
There was a problem hiding this comment.
For the case of testing a response, I think we should have a similar situation as the originally problematic one where the top-level type is nullable array. So something like schemas.MapGet("/response-array-with-nullable-element", () => TypedResults.Ok(Array.Empty<TestEnum>());
…ttps://github.com/snemeckayova/aspnetcore into dev/snemeckayova/open-api-array-element-nullability
| "schema": { | ||
| "type": "array", | ||
| "items": { | ||
| "$ref": "#/components/schemas/TestEnum" | ||
| } | ||
| } |
There was a problem hiding this comment.
We still have a bug here right?
It's existing bug so it's not a blocker to get this PR merged. But if we merge as-is, please make sure to open an issue so that we track fixing it.
Previously, an endpoint such as
app.MapGet("/", (string?[] inputs) => { });produced a schema where the array items were encoded as non-nullable. This was assumed to be a runtime limitation, since the nullability of a reference type is not part of the type itself and therefore cannot be recovered from typeof(string[]) while generating the item schema.However, the annotation is available: NullabilityInfoContext.Create(ParameterInfo) exposes NullabilityInfo.ElementType, which carries the nullability of the array's element type. This PR uses that metadata when building parameter schemas.
Changes:
• TypeExtensions.ShouldApplyNullableArrayElementSchema - resolves the element-type nullability from the parameter's ParameterInfo for array parameters.
• OpenApiSchemaExtensions.MakeArrayItemsNullable - marks array items as nullable. Inline item schemas get null added to their type keyword; item schemas that are references to shared component schemas are wrapped in a oneOf with a null schema instead of being mutated in place, so other usages of the component are unaffected.
• OpenApiDocumentService.GetParametersAsync - applies the above to the generated parameter schema.
Behavior for value-type elements (int?[], Guid?[], DateTime?[], ...) is unchanged, as those were already resolved correctly from the type itself.
Fixes #67844