dotnet / dotnet/aspnetcore

Link Generation - Incorrect Route Template Matching with literal in path

Open
#54,403 0 comments 0 reactions 0 assignees View on GitHub
area-mvc
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

### Is there an existing issue for this?

- [X] I have searched the existing issues

### Describe the bug

This may or may not be a bug, but it is certainly confounding (to me anyway) why I'm getting the results I'm getting.

This is minimal reproducible code (simplifying a post-redirect-get pattern):

```c#
public class TestController : Controller
{
[HttpGet("{ID2}/{ID1}/Test/{ID3?}")]
[HttpGet("{ID1}/Test/{ID3?}")]
public IActionResult Test(string id1, string id2, string id3)
{
return RedirectToAction("Redirected", new { ID1 = id1, ID2 = id2, ID3 = id3 });
}

[HttpGet("{ID2}/{ID1}/Redirected/{ID3?}")]
[HttpGet("{ID1}/Redirected/{ID3?}")]
public string Redirected()
{
return "Redirected";
}
}
```

### Expected Behavior

When I request `/a/test/b` I expect to be redirected to `/a/Redirected/b` (and I am).

When I request `/a/b/test/c` I expect to be redirected to `/a/b/Redirected/c`, but instead I'm redirected to `/b/Redirected/c?ID2=a`.

So its matching with a route template (that is later in the list) and has fewer matching parameters, and adding the extra parameter on as a query string.

If I add an Order to the route templates:

```c#
[HttpGet("{ID2}/{ID1}/Redirected/{ID3?}", Order = 0)]
[HttpGet("{ID1}/Redirected/{ID3?}", Order = 1)]
public string Redirected()
{
return "Redirected";
}
```

Then I am correctly redirected to `/a/b/Redirected/c`

**OR...** If I change the literal `Redirected` to a token/parameter `{action}`:

```c#
[HttpGet("{ID2}/{ID1}/{action}/{ID3?}")]
[HttpGet("{ID1}/{action}/{ID3?}")]
public string Redirected()
{
return "Redirected";
}
```

Then I am correctly redirected to `/a/b/Redirected/c`

Why does a route template with a literal in it not match properly when using RedirectToAction?

### Steps To Reproduce

This is tested in the default .NET 8 MVC template, with just this simple controller added.

Although, just to be sure the default route wasn't affecting anything, I did comment it out:

```c#
app.MapControllers();

//app.MapControllerRoute(
// name: "default",
// pattern: "{controller=Home}/{action=Index}/{id?}");
```
/

### Exceptions (if any)

_No response_

### .NET Version

8.0.201

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