In ASP.Net MVC, I want 2 different routes:
http://mysite.com/foo/12345
and
http://mysite.com/foo/bar
In the class Foo, I have 2 methods that return ActionResult
public ActionResult DetailsById(int id)
{
. . . some code
}
and
public ActionResult DetailsByName(string name)
{
. . . some code
}
How do I set up 2 routes so that if the parameter is an int, it goes to DetailsById, but otherwise goes to DetailsByName?
You can use a route constraint for the first route.
routes.MapRoute("DetailsById",
"foo/{id}",
new { controller = "foo", action = "DetailsById" },
new { id = @"\d+" } // Parameter constraints
);
routes.MapRoute("DetailsByName",
"foo/{id}",
new { controller = "foo", action = "DetailsByName" }
);
The first route will only accept ids that match the regex (which accepts numbers only). If it doesn't match the first route, it will go to the second.
Use something like this:
routes.MapRoute(
"DetailsById",
"Foo/{Id}",
new {controller="Foo", action="DetailsById"},
new {Id= @"\d+" }
);
routes.MapRoute(
"DetailsByName",
"Foo/{Name}",
new {controller="Foo", action="DetailsByName"}
);
Remember that the routes are checked from top to bottom and stop at the first match.
I'm assuming that you already have a default route set up for your id parameter.
The only thing you will need to do is add a map route in your global.asax.cs:
routes.MapRoute(
"Foo_DetailsByName",// Route name
"Foo/DetailsByName/{name}",// URL with parameters
new { controller = "Foo", action = "DetailsByName", name = String.Empty } // Parameter defaults
);
In some cases, this can be accomplished through a route constraint. A common scenario is the ability to have my domain.com/482 behave the same way as my domain.com/products/details/482, where you do not want the 482 to be matched as a controller but as a Product ID.
Route constraints are regular expressions, though, so while you can use regex to match the pattern of the route, you are not actually matching based on data type.
See: http://www.asp.net/mvc/tutorials/creating-a-route-constraint-cs