Skip to content

[AOT] Using two MapDelete() routes with distinct patterns but same parameter name lets source generator use wrong parameter source in second route #63671

@lauxjpn

Description

@lauxjpn

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

With native AOT enabled:

<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <TargetFramework>net9.0</TargetFramework>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
        <InvariantGlobalization>true</InvariantGlobalization>
        <PublishAot>true</PublishAot>
    </PropertyGroup>
</Project>

The resolution of route /test1/42 of the following code will not succeed when called like Invoke-WebRequest -Uri "http://127.0.0.1/test1/42" -Method Delete:

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateSlimBuilder(args);
var app = builder.Build();

// Invoke-WebRequest -Uri "http://127.0.0.1:80/test0?name=42" -Method Delete
// Works as expected.
app.MapDelete("/test0", ([FromQuery] string name) => Results.Ok());

// Invoke-WebRequest -Uri "http://127.0.0.1/test1/42" -Method Delete
// Fails with:
// Microsoft.AspNetCore.Http.BadHttpRequestException: Required parameter "string name" was not provided from query string.
app.MapDelete("/test1/{name}", ([FromRoute] string name) => Results.Ok());

app.Run();

The reason seems to be, that the source generator is taking the [FromQuery] attribute from the name parameter of the first route /test0, and reuses it for the name parameter of the second route /test1/{name} (same parameter name), even though the second route explicitly declares name as [FromRoute], which the source generator ignores. Thus it expects a query parameter in the Uri, even though it should expect a routing argument.

Switching the order of the route declarations in the source code will switch what the source generator expects. But the name parameter of the later declared route is always expected by the source generator to be provided in the same way as for the former declared route.

Expected Behavior

A later declared MapDelete() route should not inherit the parameter source (e.g. [FromQuery]) of earlier declared MapDelete() routes. And this inheritance should definitely not override the explicit one (e.g. [FromRoute]) declared in the later route.

Steps To Reproduce

See description.

Exceptions (if any)

Microsoft.AspNetCore.Http.BadHttpRequestException: Required parameter "string name" was not provided from query string.
   at Microsoft.AspNetCore.Http.Generated.<GeneratedRouteBuilderExtensions_g>F3631FD46BF4370BA35BC57E80ED6E2D63BA9276F07031EC5F6198ED23869E4EB__LogOrThrowExceptionHelper.RequiredParameterNotProvided(String parameterTypeName, String parameterName, String source) in D:\Projects\AspNetCoreIssues\AspNetCoreIssue\obj\Debug\net9.0\Microsoft.AspNetCore.Http.RequestDelegateGenerator\Microsoft.AspNetCore.Http.RequestDelegateGenerator.RequestDelegateGenerator\GeneratedRouteBuilderExtensions.g.cs:line 340
   at Microsoft.AspNetCore.Http.Generated.<GeneratedRouteBuilderExtensions_g>F3631FD46BF4370BA35BC57E80ED6E2D63BA9276F07031EC5F6198ED23869E4EB__GeneratedRouteBuilderExtensionsCore.<>c__DisplayClass2_0.<MapDelete0>g__RequestHandler|5(HttpContext httpContext) in D:\Projects\AspNetCoreIssues\AspNetCoreIssue\obj\Debug\net9.0\Microsoft.AspNetCore.Http.RequestDelegateGenerator\Microsoft.AspNetCore.Http.RequestDelegateGenerator.RequestDelegateGenerator\GeneratedRouteBuilderExtensions.g.cs:line 114
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

.NET Version

9.0.300

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    NativeAOTarea-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesfeature-rdg

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions