Using the out-of-the-box method locators in ASP.NET MVC (3 or 4DP), is there a way to have the MVC framework differentiate between a string and Guid without needing to parse the parameter in the controller action?
Usage examples would be for the URL
http://[domain]/customer/details/F325A917-04F4-4562-B104-AF193C41FA78
to execute the
public ActionResult Details(Guid guid)
method, and
to execute the
public ActionResult Details(string id)
method.
With no changes, obviously the methods are ambiguous, as follows:
public ActionResult Details(Guid id)
{
var model = Context.GetData(id);
return View(model);
}
public ActionResult Details(string id)
{
var model = Context.GetData(id);
return View(model);
}
resulting in the error:
The current request for action 'Details' on controller type 'DataController' is ambiguous between the following action methods:
System.Web.Mvc.ActionResult Details(System.Guid) on type Example.Web.Controllers.DataController
System.Web.Mvc.ActionResult Details(System.String) on type Example.Web.Controllers.DataController
I attempted to use a custom constraint (based on How can I create a route constraint of type System.Guid?) to try and push it through via routing:
routes.MapRoute(
"Guid",
"{controller}/{action}/{guid}",
new { controller = "Home", action = "Index" },
new { guid = new GuidConstraint() }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
And switched the action signatures to:
public ActionResult Details(Guid guid)
{
var model = Context.GetData(guid);
return View(model);
}
public ActionResult Details(string id)
{
var model = Context.GetData(id);
return View(model);
}
The constraint executes and passes, thus the argument is sent to an action, but seemingly still as a string, and thus ambiguous to the two method signatures. I expect that there's something in how the action methods are located that causes the ambiguity, and thus could be overridden by plugging in a custom module to locate methods.
The same result could be achieved by parsing out the string parameter, but would be really nice for brevity to avoid that logic in the action (not to mention to hopefully reuse someday later).
See Question&Answers more detail:os