Search code examples
c#asp.net-core-mvc.net-coreasp.net-core-2.0asp.net-routing

Where is Url.Action getting these values from?


I'm trying to create a link to the following GET action with Url.Action:

public class FooController : Controller
{
    [HttpGet]
    [Route("Foo/Apply/BarDetails/Part/{id}")]
    public IActionResult BarDetails(int id)
    {
    }
}

And in my view I'm creating a URL with

Url.Action("BarDetails", "Foo", new {id = 1})

However this generates the URL Foo/Apply/BarDetails/Part/10?id=1 which is definitely not what I want! Removing the values parameter simply removes the query string part of the URL. The only route I have registered at startup is

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});

I've had a look at the ASP.NET Core source and I suspect that the "10" part of the URL is coming from a "1" + "0" operation somewhere as the routing code is split across 2+ repos it's hard to follow. Does anyone know how the last part of this URL is being generated and how I can fix it to match the id provided in the route values?


Solution

  • It turns out that routing has changed between MVC5 (where this controller was written) and ASP.NET Core 2. It's also related to the way I've structured my controller. Basically at some point the list of possible routes gets sorted by the URL so Foo/Apply/BarDetails/Part/10 gets sorted to the top of the list and as this matches the requested URL, it gets returned. For the full details, see this GitHub issue.