Skip to content

Fix optional non-nullable struct query parameters with = default throwing in RequestDelegateFactory#66091

Open
Copilot wants to merge 3 commits intomainfrom
copilot/fix-minimal-api-optional-struct-params
Open

Fix optional non-nullable struct query parameters with = default throwing in RequestDelegateFactory#66091
Copilot wants to merge 3 commits intomainfrom
copilot/fix-minimal-api-optional-struct-params

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 1, 2026

Reflection reports DefaultValue == null for non-nullable struct parameters with = default (e.g., Guid, DateTime, TimeSpan). CreateDefaultValueExpression was passing that null directly to Expression.Constant(null, parameterType), which throws ArgumentException: Argument types do not match for non-nullable value types.

Description

  • RequestDelegateFactory.cs: In CreateDefaultValueExpression, when defaultValue is null and parameterType is a non-nullable value type, use Expression.Default(parameterType) instead of Expression.Constant(null, parameterType).
  • RequestDelegateCreationTests.QueryParameters.cs: Added tests covering Guid and DateTime optional parameters with = default, both with and without a query string value provided. Tests are placed in RequestDelegateCreationTests.QueryParameters.cs so they run against both RequestDelegateFactory (via RuntimeCreationTests) and RequestDelegateGenerator (via CompileTimeCreationTests).
// Previously threw ArgumentException at first request; now works correctly
app.MapGet("/ok", ([FromQuery] Guid id = default, [FromQuery] DateTime date = default) => Results.Ok());
  • You've read the Contributor Guide and Code of Conduct.
  • You've included unit or integration tests for your change, where applicable.
  • You've included inline docs for your change, where applicable.
  • There's an open issue for the PR that you are making. If you'd like to propose a new feature or change, please open an issue to discuss the change or find an existing issue.

…n RequestDelegateFactory

Agent-Logs-Url: https://github.com/dotnet/aspnetcore/sessions/b06c1d39-20b4-4060-bca6-72f07cbf08ad

Co-authored-by: BrennanConroy <7574801+BrennanConroy@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix minimal APIs: handle optional non-nullable struct query parameters Fix optional non-nullable struct query parameters with = default throwing in RequestDelegateFactory Apr 1, 2026
Copilot AI requested a review from BrennanConroy April 1, 2026 21:42
@github-actions github-actions bot added the area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions label Apr 1, 2026
Comment thread src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs Outdated
…Parameters.cs

Agent-Logs-Url: https://github.com/dotnet/aspnetcore/sessions/ae7b0e98-8ab8-436c-9727-b09547e4abba

Co-authored-by: BrennanConroy <7574801+BrennanConroy@users.noreply.github.com>
@BrennanConroy BrennanConroy marked this pull request as ready for review April 2, 2026 00:57
@BrennanConroy BrennanConroy requested a review from halter73 as a code owner April 2, 2026 00:57
Copilot AI review requested due to automatic review settings April 2, 2026 00:57
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a runtime exception in minimal API binding when optional non-nullable struct query parameters use = default (reflection reports DefaultValue == null, which previously caused an invalid Expression.Constant(null, valueType)).

Changes:

  • Update RequestDelegateFactory.CreateDefaultValueExpression to use Expression.Default(parameterType) when defaultValue is null for non-nullable value types.
  • Add generator/runtime coverage for optional [FromQuery] Guid and [FromQuery] DateTime parameters declared with = default, with and without query values.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/Http/Http.Extensions/src/RequestDelegateFactory.cs Prevents ArgumentException by emitting a default(T) expression for non-nullable value types when reflection returns DefaultValue == null.
src/Http/Http.Extensions/test/RequestDelegateGenerator/RequestDelegateCreationTests.QueryParameters.cs Adds regression tests for optional struct query parameters using = default across runtime (factory) and compile-time (generator) paths.

Comment on lines +142 to +146
[Theory]
[InlineData(null, "Id: 00000000-0000-0000-0000-000000000000")]
[InlineData("a0e1f2b3-c4d5-4e6f-7a8b-9c0d1e2f3a4b", "Id: a0e1f2b3-c4d5-4e6f-7a8b-9c0d1e2f3a4b")]
public async Task CanSetGuidParamAsOptionalWithDefaultValue(string queryValue, string expectedResponse)
{
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

queryValue is passed as null via [InlineData(null, ...)], but the parameter is declared as non-nullable string. Consider changing it to string? queryValue so the signature matches the test data and avoids nullable-analysis warnings.

Copilot uses AI. Check for mistakes.
[Theory]
[InlineData(null, "Date: 0001-01-01T00:00:00.0000000")]
[InlineData("2024-01-15", "Date: 2024-01-15T00:00:00.0000000")]
public async Task CanSetDateTimeParamAsOptionalWithDefaultValue(string queryValue, string expectedResponse)
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

queryValue is provided as null in one [InlineData] case, but the parameter is declared string (non-nullable). Update it to string? queryValue to accurately model the test inputs and avoid nullable warnings.

Suggested change
public async Task CanSetDateTimeParamAsOptionalWithDefaultValue(string queryValue, string expectedResponse)
public async Task CanSetDateTimeParamAsOptionalWithDefaultValue(string? queryValue, string expectedResponse)

Copilot uses AI. Check for mistakes.
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Looks like this PR hasn't been active for some time and the codebase could have been changed in the meantime.
To make sure no conflicting changes have occurred, please rerun validation before merging. You can do this by leaving an /azp run comment here (requires commit rights), or by simply closing and reopening.

@dotnet-policy-service dotnet-policy-service bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Minimal APIs: optional non-nullable struct query parameters with = default throw in RequestDelegateFactory

3 participants