Самый простой способ исправить это - зарегистрировать маршруты для 5, 4,3 и 2 параметров.Зарегистрируйте их в этом порядке.
{controller}/{one}/{two}/{three}/{four}/{five}/{productdetail}
{controller}/{one}/{two}/{three}/{four}/{productdetail}
{controller}/{one}/{two}/{three}/{productdetail}
{controller}/{one}/{two}/{productdetail}
Невозможно зарегистрировать маршрут для {controller} / {one} / {productdetail} без создания ограничения маршрута, чтобы убедиться, что {one} не является действием {контроллер}.
Я бы настоятельно рекомендовал, чтобы, если у вас есть списки вариантов 1 - 5, МОЖЕТ БЫТЬ, что вы создаете пользовательское ограничение маршрута, которое будет проверять их, чтобы вы случайно не соответствовали маршруту, который вы не намеревались, новы должны быть в безопасности с указанными выше маршрутами.
Создание IRouteConstraint не сложно.Ниже приведен код, который я ранее использовал для ограничения маршрута, которое позволяло бы вызывать действие из определенного контроллера без необходимости указывать контроллер.Примером может служить контроллер под названием Home с действием для «О программе», это ограничение позволит вам вызывать / about вместо /home/about.
Это относится к тому, что вы хотите сделать, потому что оно показываеткак выполнить некоторую проверку, чтобы определить разницу между {one} и {action}, если вам нужно.
Ограничение маршрута:
public class IsRootActionConstraint : IRouteConstraint
{
private List<string> _actions;
public IsRootActionConstraint(): this( "homecontroller")
{
}
public IsRootActionConstraint(string ControllerName)
{
Type _type = Assembly
.GetCallingAssembly()
.GetTypes()
.Where(type => type.IsSubclassOf(typeof(Controller)) && type.Name.ToLower() == ControllerName.ToLower())
.SingleOrDefault();
if (_type != null)
{
_actions = (from methods in _type.GetMethods() where typeof(ActionResult).IsAssignableFrom(methods.ReturnType) select methods.Name.ToLower()).ToList();
}
}
#region IRouteConstraint Members
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
return _actions.Contains((values["action"] as string).ToLower());
}
#endregion
}
И когда вы регистрируете свой маршрут вglobal.asax:
routes.MapRoute(
"Home",
"{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { IsRootAction = new CAA.Utility.Constraints.IsRootActionConstraint() } // Route Constraint
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
В вашем случае проверка того, что {one} не соответствует маршруту в {controller}, не должна быть слишком сложной.Вы можете переместить код отражения в метод Match и использовать имя из значений маршрута для контроллера, чтобы найти действия.