Is there an existing issue for this?
Describe the bug
When you have a minimal API that takes a string[] (or StringValues) parameter which binds to the querystring, for example:
app.MapGet("/", (string[] q) => q);
calling the API without a querystring (e.g. /) should give a 400 response saying BadHttpRequestException: Required parameter "string[] q" was not provided from query string.
But this does not happen - instead q is an empty array. This differs from both of the following other examples:
app.MapGet("/", (string q) => q); //
app.MapGet("/", (StringValues q) => q);
which both return a 400 response as expected.
Expected Behavior
When binding a required parameter in a minimal API, a value must be present in the binding source (typically the querystring when binding arrays), otherwise the API returns a 400. This is the documented behaviour which works for other parameter types.
Steps To Reproduce
To reproduce, create an api like this: app.MapGet("/", (string[] q) => q); and call the URL / (without a querystring). The response is [], where it should be a 400 Bad Request.
Exceptions (if any)
No response
.NET Version
7.0.101
Anything else?
I found this behaviour while reading some of the Expression generation code in RequestDelegateFactory. In particular CreateArgument() calls BindParameterFromValue which calls BindParameterFromExpression.
The argument expression generated by this code when binding a string[] parameter (called q in this example) to the querystring is similar to the following (some artisitic license):
Task Invoke(HttpContext httpContext)
{
bool wasParamCheckFailure = false; // Added by RequestDelegateFactory.Create()
string[] q_local = httpContext.Request.Query["q"] // 👈 This is the problem
if (q_local == null) // 👈 Because this is never true.
{
wasParamCheckFailure = true;
Log.RequiredParameterNotProvided(httpContext, "string[]", "q", "query");
}
if(wasParamCheckFailure) // Added by RequestDelegateFactory.Create()
{
httpContext.Response.StatusCode = 400;
return Task.CompletedTask;
}
// .. call handler, handle response
}
I think the problem lies in the line above. Query["q"] returns StringValues.Empty when the item is not present, and is implicitly converted to a string[]. (string[])StringValues.Empty always returns an empty array, so is never null, so the check never succeeds.
Is there an existing issue for this?
Describe the bug
When you have a minimal API that takes a
string[](orStringValues) parameter which binds to the querystring, for example:calling the API without a querystring (e.g.
/) should give a 400 response sayingBadHttpRequestException: Required parameter "string[] q" was not provided from query string.But this does not happen - instead
qis an empty array. This differs from both of the following other examples:which both return a 400 response as expected.
Expected Behavior
When binding a required parameter in a minimal API, a value must be present in the binding source (typically the querystring when binding arrays), otherwise the API returns a 400. This is the documented behaviour which works for other parameter types.
Steps To Reproduce
To reproduce, create an api like this:
app.MapGet("/", (string[] q) => q);and call the URL/(without a querystring). The response is[], where it should be a 400 Bad Request.Exceptions (if any)
No response
.NET Version
7.0.101
Anything else?
I found this behaviour while reading some of the
Expressiongeneration code inRequestDelegateFactory. In particularCreateArgument()callsBindParameterFromValuewhich callsBindParameterFromExpression.The argument expression generated by this code when binding a
string[]parameter (calledqin this example) to the querystring is similar to the following (some artisitic license):I think the problem lies in the line above.
Query["q"]returnsStringValues.Emptywhen the item is not present, and is implicitly converted to astring[].(string[])StringValues.Emptyalways returns an empty array, so is nevernull, so the check never succeeds.