Search code examples
asp.net-core-mvcasp.net-routingasp.net-core-routing

ASP.NET Core MVC virtual path generation incorrect when including an Id within an Area


I'm working in an ASP.NET Core 2.0 MVC app and I'm trying to build a URL using the routing information. Everything works just fine as long as I stick with Area, Controller, and Action. As soon as I try to use Id, the path comes back incorrect

When I include everything except the id I get what I would expect

<a asp-area="Admin" asp-controller="Users" asp-action="Detail">User detail</a>

or from inside the UsersController

Url.Action("Detail")

produces

http://localhost:55556/Admin/Users/Detail

When I include the id

<a asp-area="Admin" asp-controller="Users" asp-action="Detail" asp-route-id="1">User detail</a>

or

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

I get only

http://localhost:55556/1

This is what my routes look like

routes.MapRoute(
    name: "areas",
    template: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
);

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

Can anyone see where I'm going wrong?

Update

It seems to have to do with the Area. When I leave the area out it produces what I would expect

Url.Action("Detail", "Users", new { id = 1 })

produces

/Users/Detail/1

Even though that doesn't actually exist. Though when I add the area

Url.Action("Detail", "Users", new { id = 1, area = "Admin" })

I get

/1

Has anyone else had trouble with Area routing?


Solution

  • I figured it out. I had an incorrect [HttpGet] attribute on the action.

    I had

    [HttpGet("{id:int}")]
    public ActionResult Detail(int id)
    {
        var user = _userRepository.GetUserById(id);
        var model = Mapper.Map<User, UserDetailModel>(user);
    
        return View(model);
    }
    

    Not realizing that the route I set into the attribute overwrote the default in full, and didn't just apply to the argument

    I removed the the ("{id:int}") and everything worked great