首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在ASP.NET MVC3中自定义将url动态映射到组合命名控制器的路由

如何在ASP.NET MVC3中自定义将url动态映射到组合命名控制器的路由
EN

Stack Overflow用户
提问于 2012-11-28 09:50:56
回答 1查看 536关注 0票数 3

我需要这样的URL地图:

/股票/风险->StockRiskController.Index()

/股票/风险/attr>StockRiskController.Attr()

/srock/risk/图表->StockRiskController.Chart()

..。

/债券/性能->BondPerformanceController.Index()

//performance/attr>BondPerformanceController.Attr()

/债券/性能/图表->BondPerformanceController.Chart().

第一部分是动态的,但是可枚举的,第二部分只有两个选项(风险-性能)。

目前我只知道两种方法:

  1. 定制一个ControllerFactory(似乎被杀过头或太复杂)
  2. 硬编码所有的组合,因为它们是可枚举的(丑陋的)。

我可以使用routes.MapRoute来实现这一点吗?或者其他方便的方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-28 14:12:26

有一个很好的基于IRouteConstraint的解决方案。首先,我们必须创建新的路径映射:

代码语言:javascript
复制
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() }
);

下一步是创建约束。在我介绍一些方法之前,我将介绍如何检查上面提到的两个列表中的相关性,以及可能的值,但是逻辑是可以调整的。

代码语言:javascript
复制
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方法,它将根据需要调整路由。

代码语言:javascript
复制
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;
}

您可以更多地使用这种方法,但是现在的概念应该是明确的。

注:我喜欢你的做法。有时,扩展/调整路由、然后转到代码和“修复名称”更重要。类似的解决方案也在这里工作:https://stackoverflow.com/questions/13423545

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13602238

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档