【问题标题】:How can I get the route name in controller in ASP.NET MVC?如何在 ASP.NET MVC 的控制器中获取路由名称?
【发布时间】:2008-12-12 16:15:32
【问题描述】:

ASP.NET MVC 路由在映射时具有名称:

routes.MapRoute(
    "Debug", // Route name -- how can I use this later????
    "debug/{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = string.Empty } );

有没有办法获取路线名称,例如上例中的“调试”?我想在控制器的 OnActionExecuting 中访问它,以便在调试时可以在 ViewData 中设置内容,例如,通过在 URL 前加上 /debug/...

【问题讨论】:

    标签: asp.net-mvc model-view-controller routing


    【解决方案1】:

    不幸的是,路线名称没有存储在路线中。它只是在 MVC 内部用作集合中的键。例如,我认为这是您在使用 HtmlHelper.RouteLink 创建链接时仍然可以使用的东西(也许在其他地方也是如此,不知道)。

    无论如何,我也需要它,这就是我所做的:

    public static class RouteCollectionExtensions
    {
        public static Route MapRouteWithName(this RouteCollection routes,
        string name, string url, object defaults, object constraints)
        {
            Route route = routes.MapRoute(name, url, defaults, constraints);
            route.DataTokens = new RouteValueDictionary();
            route.DataTokens.Add("RouteName", name);
    
            return route;
        }
    }
    

    所以我可以像这样注册一条路线:

    routes.MapRouteWithName(
        "myRouteName",
        "{controller}/{action}/{username}",
        new { controller = "Home", action = "List" }
        );
    

    在我的控制器操作中,我可以通过以下方式访问路由名称:

    RouteData.DataTokens["RouteName"]
    

    希望对您有所帮助。

    【讨论】:

    • 很酷的解决方法,尽管 MVC 不授予访问权限似乎是一种疏忽。你是对的 - 你可以通过指定名称来创建一个路由链接,所以它存储在某个地方:-)
    • 这不是路由名称的目的。该名称旨在在使用路由生成 URL 时提供索引,允许您指定要使用的路由。 DataTokens 确实是做到这一点的正确方法。例如,假设您有多个“调试”路由。无论如何,您不能为其使用名称。但是您始终可以创建自己的数据令牌。路由会忽略数据标记,但会传递它们,以便您的代码可以解释它们的含义。
    • 仍然是一个疏忽,原因有两个:首先,人们显然觉得它很有用;其次,为什么 MapRoute 将名称作为参数,但是在使用构造函数构造新路由时没有 Name 参数在里面。
    • 这里有另一种非常相似的方法haacked.com/archive/2010/11/28/…
    • @mare 当一个框架没有包含任何人可能想要的所有可能的特性时,这并不等同于“疏忽”。你的第二个理由没有任何意义。这就像在说“为什么Dictionary<string, string>.Add()key 作为参数,但是在使用构造函数构造新字符串时,其中没有key 参数?”路由名称是路由的标识符。它不是路由的属性。
    【解决方案2】:

    如果使用如下标准 MapRoute 设置:

    routes.MapRoute(    name: "Default",
                        url: "{controller}/{action}/{id}",
                        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    

    ...这将在视图中起作用...

    var routeName = Url.RequestContext.RouteData.Values["action"].ToString();
    

    【讨论】:

      【解决方案3】:

      您可以使用附加参数的默认值通过路由值传递路由名称:

      routes.MapRoute(
          name: "MyRoute",
          url: "{controller}/{action}/{id}",
          defaults: new { routeName = "MyRoute", controller = "Home", action = "Index", id=UrlParameter.Optional }
      );
      

      然后,就可以从控制器上下文中获取传递的值了:

      string routeName = ControllerContext.RouteData.Values["routeName"].ToString();
      

      【讨论】:

        【解决方案4】:

        这并没有直接回答问题(如果你想学究气的话);但是,真正的目标似乎是在给定路由名称的情况下获取路由的基本 URL。所以,这就是我的做法:

        我的路线在RouteConfig.cs 中定义为:

        routes.MapRoute(
                    name: "MyRoute",
                    url: "Cont/Act/{blabla}",
                    defaults: new { controller = "Cont", action = "Act"}
                );
        

        并获取路由的基本 URL:

        var myRoute = Url.RouteUrl("MyRoute", new { blabla = "blabla" }).Replace("blabla", "");
        

        它给了我想要的路由的基本 URL:

        /Cont/Act/
        

        希望这会有所帮助。

        【讨论】:

          【解决方案5】:

          另一种解决方案是使用解决方案配置:

          protected override OnActionExecuting()
          {
              #if DEBUG
          
                  // set up stuff in the ViewData
          
              #endif
          
              // continue
          }
          

          真的不需要像这样引用路由名称——我想这就是为什么 MVC 让做这种事情变得如此困难。

          【讨论】:

            【解决方案6】:

            另一个选项 - 使用带有 string[] 命名空间参数的 MapRoute,然后你可以看到你的命名空间为 RouteData.DataTokens["Namespaces"]

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-11-18
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多