Всегда ли ID гарантированно будет числом? Если да, то вы можете использовать RouteConstraints :
routes.MapRoute("ActionIDRoute",
"{action}/{id}",
new { controller = "SomeController" },
new {id= new IDConstraint()});
routes.MapRoute("ControllerActionRoute",
"{controller}/{action}",
new {}); // not sure about this last line
Класс IDConstraint выглядит следующим образом:
public class IDConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route,
string parameterName, RouteValueDictionary values,
RouteDirection routeDirection)
{
var value = values[parameterName] as string;
int ID;
return int.TryParse(value,out ID);
}
}
В основном происходит то, что у вас есть два одинаковых маршрута - два параметра, так что это неоднозначно. Ограничения маршрута применяются к параметрам, чтобы увидеть, совпадают ли они.
Итак:
- Звоните http://localhost/SomeController/SomeAction
- Он попадет в ActionIDRoute, так как у него два заполнителя
- Поскольку существует ограничение на параметр id (SomeAction), ASP.net MVC вызовет функцию Match ()
- При сбое int.TryParse в SomeAction маршрут отбрасывается
- Следующий соответствующий маршрут - ControllerActionRoute
- Поскольку это соответствует и на него нет ограничений, будет принято
Если ID не гарантированно является числом, значит, у вас возникла проблема с устранением неоднозначности. Единственное известное мне решение - это жесткое кодирование маршрутов, где применяется {action} / {id}, что не всегда возможно.