Asp.net mvc 如何在ASP.NET MVC3中自定义将url动态映射到组合命名控制器的路由
我需要像这样映射URL: /股票/风险-->Asp.net mvc 如何在ASP.NET MVC3中自定义将url动态映射到组合命名控制器的路由,asp.net-mvc,asp.net-mvc-3,Asp.net Mvc,Asp.net Mvc 3,我需要像这样映射URL: /股票/风险-->StockRiskController.Index() /股票/风险/属性-->StockRiskController.attr() /srock/risk/chart-->StockRiskController.chart() /绑定/性能-->BondPerformanceController.Index() /bond/performance/attr-->BondPerformanceController.attr() /bond/perfo
StockRiskController.Index()
/股票/风险/属性-->StockRiskController.attr()
/srock/risk/chart-->StockRiskController.chart()
/绑定/性能-->BondPerformanceController.Index()
/bond/performance/attr-->BondPerformanceController.attr()
/bond/performance/chart-->BondPerformanceController.chart()
第一部分是动态但可枚举的,第二部分只有两个选项(风险|绩效)
目前我只知道两种方法:
我可以使用
routes.MapRoute
来实现这一点吗?还是其他方便的方法?有一个基于irouteconsttraint
的很好的解决方案。首先,我们必须创建新的路线映射:
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" };
...
您可以更多地使用这种方法,但现在概念应该清楚了
注:我喜欢你的方法。有时,扩展/调整路由比使用代码和“修复名称”更为重要。类似的解决方案也适用于此:据我所知,您的最后一部分是您的行动,因此我认为您可以使用类似的方法。映射路由中的{controller}/*/{action}。嗯,我知道这行不通,但这是一个开始。@OnurTOPAL,你说得对。然而,因为我们已经有了一个可操作的版本,其中包含丑陋的url,如“BondPerformance/Index | Attr |……”,我们只想在不影响任何逻辑的情况下更改url。因此,我认为我应该对路线做点什么。我认为,如果您希望避免对每个
债券|股票/风险|绩效
组合的路线进行硬编码,那么选项1是您唯一的选择。工作起来很有魅力。我不知道约束是否有机会更改RouteValueDictionary。非常感谢。
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;
}