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
…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.
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

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