Search code examples
c#asp.net-mvcmodel-view-controllerasp.net-mvc-areasareas

Why is MVC Area Routing not working as expected?


I have the following area set up on my site.

public class AdminAreaRegistration : AreaRegistration
{
    public override string AreaName
    {
        get
        {
            return "Admin";
        }
    }

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            "AdminDefaultNoAction",
            "Admin/{controller}/{id}",
            new { action = "Home", id = UrlParameter.Optional }, new[] { "DevTest.Areas.Admin.Controllers" }
        );

        context.MapRoute(
            "AdminDefault",
            "Admin/{controller}/{action}/{id}",
            new { action = "Home", id = UrlParameter.Optional }, new[] { "DevTest.Areas.Admin.Controllers" }
        );
    }
}

And the following methods in my controller.

public class PlayerController : Controller
{
    public PlayerController()
    {

    }

    [HttpGet]
    public ActionResult Home(Guid id)
    {
        var model = new HomeViewModel();
        // Do Stuff
        return View("Home", model);
    }

    [HttpPost]
    public ActionResult Home(HomeViewModel model)
    {
        // Do Stuff
        return View("Home", model);
    }

    public ActionResult TestMethod(Guid id)
    {
        return Json(new
        {
            Test = "Hi!",
            id = id.ToString()
        });
    }
}

My two home methods work fine. TestMethod works if I hit it with Admin/Player/TestMethod/e0ef4ab3-3fe5-4ea8-8ae1-c16b9defcabe" but fails if I hit it with Admin/Player/TestMethod?id=e0ef4ab3-3fe5-4ea8-8ae1-c16b9defcabe.

This is obviously just a demonstrative example. I want to be able to hit some methods in this Controller passing values in (mostly via ajax requests) but the routing is not working as intended.

Thanks in advance.


Solution

  • As noted by @Stephen Muecke in the comments, my first route was not specific enough. I had to constrain the id to be a guid for it to work as intended.

    I did this with a regex as I'm still using Mvc version 4.

    context.MapRoute(
        "AdminDefaultNoAction",
        "Admin/{controller}/{id}",
        new { action = "Home", id = UrlParameter.Optional },
        new { id = @"[a-f0-9-]+" },
        new[] { "DevTest.Areas.Admin.Controllers" }
    );
    

    If I had Mvc 5 I could have used:

    new { guid = new GuidRouteConstraint() }