Skip to content

Support nullable array element types in parameter schemas - #68250

Open
snemeckayova wants to merge 5 commits into
dotnet:mainfrom
snemeckayova:dev/snemeckayova/open-api-array-element-nullability
Open

Support nullable array element types in parameter schemas#68250
snemeckayova wants to merge 5 commits into
dotnet:mainfrom
snemeckayova:dev/snemeckayova/open-api-array-element-nullability

Conversation

@snemeckayova

Copy link
Copy Markdown
Contributor

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

@snemeckayova snemeckayova self-assigned this Aug 6, 2026
Copilot AI review requested due to automatic review settings August 6, 2026 10:29
@snemeckayova
snemeckayova requested a review from a team as a code owner August 6, 2026 10:29
@snemeckayova
snemeckayova force-pushed the dev/snemeckayova/open-api-array-element-nullability branch from 62dcb7d to 1684f4d Compare August 6, 2026 10:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 MakeArrayItemsNullable to mark array item schemas nullable, wrapping referenced component item schemas in oneOf to 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 else branch (wrapping Items in oneOf to 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?[] where SomePoco is emitted as a #/components/schemas/* reference). Please add a test that asserts the item schema becomes a oneOf: [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 Youssef1313 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 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 is Model[]? The goal is to ensure if both are componentized, we still get the correct nullability.

@Youssef1313 Youssef1313 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When adding integration tests, let's also make sure we have a test for this when it's part of the API response

Comment thread src/OpenApi/src/Services/OpenApiDocumentService.cs
// 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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>());

Comment on lines +1844 to +1849
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/TestEnum"
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@Youssef1313 Youssef1313 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ensure test coverage and correct behavior for OpenAPI when minimal API parameter is T?[]

3 participants