Как настроить маршрут для динамической привязки url к составленному именованному контроллеру в ASP.NET MVC3
Мне нужно сопоставить URL-адреса следующим образом:
/ акции / риск -->StockRiskController.Index()
/ акции / риск / АТР -->StockRiskController.Attr()
/ srock / риск / Диаграмма -->StockRiskController.Chart()
...
/ связь / производительность -->BondPerformanceController.Index()
/ связь / производительность / attr -->BondPerformanceController.Attr()
/ облигации / производительность / график -->BondPerformanceController.Chart()
...
На данный момент я знаю только два способа:
- настроил ControllerFactory (кажется переполненным или сложным)
- жестко кодируйте все комбинации, потому что они перечислимы(уродливы).
Могу ли я использовать routes.MapRoute
для достижения этой цели? Или любым другим удобным способом?
1 ответ:
Есть хорошее решение, основанное на
IRouteConstraint
. Прежде всего, мы должны создать новое отображение маршрута:Следующий шаг-создать наше ограничение. Прежде чем я представлю некоторый способ, как проверить релевантность, как упоминалось выше - два списка с возможными значениями, но логика может быть скорректированаroutes.MapRoute( name: "PrefixedMap", url: "{prefix}/{body}/{action}/{id}", defaults: new { prefix = string.Empty, body = string.Empty , action = "Index", id = string.Empty }, constraints: new { lang = new MyRouteConstraint() } );
public class MyRouteConstraint : IRouteConstraint { public readonly IList<string> ControllerPrefixes = new List<string> { "stock", "bond" }; public readonly IList<string> ControllerBodies = new List<string> { "risk", "performance" }; ...
А теперь метод Match, который будет корректировать маршрут так, как нам нужно
Вы можете играть с этим методом больше, но теперь концепция должна быть ясна.public bool Match(System.Web.HttpContextBase httpContext , Route route, string parameterName, RouteValueDictionary values , RouteDirection routeDirection) { // for now skip the Url generation if (routeDirection.Equals(RouteDirection.UrlGeneration)) { return false; } // try to find out our parameters string prefix = values["prefix"].ToString(); string body = values["body"].ToString(); var arePartsKnown = ControllerPrefixes.Contains(prefix, StringComparer.InvariantCultureIgnoreCase) && ControllerBodies.Contains(body, StringComparer.InvariantCultureIgnoreCase); // not our case if (!arePartsKnown) { return false; } // change controller value values["controller"] = prefix + body; values.Remove("prefix"); values.Remove("body"); return true; }
Примечание: мне нравится ваш подход. Иногда просто гораздо важнее расширить / настроить маршрутизацию, а затем перейти к коду и "исправить имена". Аналогичное решение работало и здесь: динамически модифицируйте RouteValueDictionary