我需要映射这样的网址:
/ stock / risk - > StockRiskController.Index()
/ stock / risk / attr - > StockRiskController.Attr()
/ srock / risk / chart - > StockRiskController.Chart()
...
/ bond / performance - > BondPerformanceController.Index()
/ bond / performance / attr - > BondPerformanceController.Attr()
/ bond / performance / chart - > BondPerformanceController.Chart()
...
第一部分是动态但可枚举,第二部分只有两个选项(风险|性能)。
目前我只知道两种方式:
我可以使用routes.MapRoute
来实现这一目标吗?还是其他任何方便的方式?
答案 0 :(得分:2)
有一个基于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;
}
你可以更多地使用这种方法,但现在应该清楚这个概念。
注意:我喜欢你的方法。有时,扩展/调整路由然后转到代码并“修改名称”更为重要。类似的解决方案在这里工作:Dynamically modify RouteValueDictionary