Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 如何在ASP.NET MVC3中自定义将url动态映射到组合命名控制器的路由_Asp.net Mvc_Asp.net Mvc 3 - Fatal编程技术网

Asp.net mvc 如何在ASP.NET MVC3中自定义将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

我需要像这样映射URL:

/股票/风险-->
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;
    }