Link Generation - Incorrect Route Template Matching with literal in path
- 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
Assessment
This issue has not been assessed yet.