1

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.

Farhan Yaseen
  • 2,507
  • 2
  • 22
  • 37
Mark Seymour
  • 111
  • 4
  • 16
  • Try setting `maxQueryString` parameter in web.config file to larger limit or get rid of it, see this similar issue: https://stackoverflow.com/questions/16605632/mvc-querystring-with-guid-returns-404. – Tetsuya Yamamoto Oct 25 '17 at 10:03
  • Your routes do not really make sense. The first one matches any url with `Admin` followed by one or 2 segments, so `Admin/Player/TestMethod?id=e0ef4ab3-3fe5-4ea8-8ae1-c16b9defcabe` ,matches it and goes to the `Home()` method of `PlayerController` and passes "TestMethod" to the `id` parameter –  Oct 25 '17 at 10:06
  • Just delete your first route (its not clear what its for) or add a constraint to the `{id}` segment to ensure its a `Guid` –  Oct 25 '17 at 10:08
  • @Stephen Muecke I deleted the first route, as you said and that did fix this. However, I now cannot do a request like "Admin/Player/[guid]" and have it route to my specified default action. How can I setup my Area Route config to achieve both? TIA – Mark Seymour Oct 25 '17 at 10:36
  • You can add a route constraint (so that if its not a `Guid` it does not match the `AdminDefaultNoAction` route and falls through to the `AdminDefault` route –  Oct 25 '17 at 10:41
  • For an example, refer [these answers](https://stackoverflow.com/questions/2421995/how-can-i-create-a-route-constraint-of-type-system-guid) –  Oct 25 '17 at 10:42
  • @Stephen Muecke Had to google how to do that, but it's working for both now. Thank you. – Mark Seymour Oct 25 '17 at 10:50
  • Your routing is misconfigured. See [Why map special routes first before common routes in asp.net mvc?](https://stackoverflow.com/a/35674633/181087) – NightOwl888 Oct 25 '17 at 14:44

1 Answers1

0

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() }
Mark Seymour
  • 111
  • 4
  • 16