dotnet / dotnet/aspnetcore

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

Open
#63,671 0 comments 0 reactions 0 assignees View on GitHub
area-mvc feature-rdg NativeAOT
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Describe the bug

With native AOT enabled:
```xml


net9.0
enable
enable
true
true

```

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`:

```cs
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.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.F3631FD46BF4370BA35BC57E80ED6E2D63BA9276F07031EC5F6198ED23869E4EB__GeneratedRouteBuilderExtensionsCore.<>c__DisplayClass2_0.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_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.