【问题标题】:Html.ActionLink construct wrong link when a non-mvc route is added添加非mvc路由时Html.ActionLink构造错误链接
【发布时间】:2010-12-01 01:21:33
【问题描述】:

我在这里有一个混合了 webform 和 mvc 的应用程序。我指定路由如下

        routes.Add("AspxRoute", new Route("Upload/New", new WebFormRouteHandler<Page>("~/Uploads.aspx")));

        routes.MapRoute(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );   

所以“上传/新建”的虚拟路径实际上映射到一个 aspx 网络表单页面。

但我的问题是 Html.ActionLink("Test", "Controller", "Action") 现在呈现

/Upload/New?Controller=Controller&Action=Action

查看了 MVC 源代码,我知道这是因为 ActionLink 调用了 RouteCollection.GetVirtualPath(requestContext, routeName, mergedRouteValues),其中 routeName 为空。不知何故,这默认使用 AspxRoute 路由来构造 url。我试图在“AspxRoute”之前添加另一条路由,但它似乎总是默认为非 mvc 路由处理程序。

当 routeName 为空时,RouteCollection.GetVirtualPath 的行为如何?为什么我的情况会这样?

如何构建正确的网址?我需要编写一个新的 Htmlhelper 扩展吗?

干杯

【问题讨论】:

    标签: asp.net-mvc webforms asp.net-mvc-routing


    【解决方案1】:

    强制路由默认没有控制器:

    var routeDefaults = new RouteValueDictionary() { { "controller", null } };
    routes.Add("RouteName", new Route("some/path", routeDefaults, new SomeHandler()));
    

    【讨论】:

      【解决方案2】:

      我遇到了同样的情况,路线“入站”正常工作,但 Html.ActionLink() 选择了错误的路线。我通过添加路由约束来解决它,以便 controller 必须为空:

      var constraints = new RouteValueDictionary()
      {
          { "controller", string.Empty }
      };
      
      routes.Add(new Route("sso/server", null, constraints, new OpenIDServerRouteHandler()));
      
      routes.MapRoute(
          name: "Default",
          url: "{controller}/{action}/{identity}",
          defaults: new { controller = "Pages", action = "Home", identity = UrlParameter.Optional }
      );
      

      由于“控制器”路由值被限制为无,对 ActionLink() 的调用最终会忽略该路由。希望这对某人有帮助!

      【讨论】:

        【解决方案3】:

        另外:确保您的默认路由是路由表中的最后一个条目。这是另一种简单的方法来结束您获得的那种 html 操作链接。

        【讨论】:

        • 很久以前的问题仍然得到答案:-) 如果您查看我附加的代码,它是路由表中的最后一个条目。 MVC.net 已经走了很长一段路,也许一切都变了,我不知道!
        【解决方案4】:

        另一种选择是将自定义约束添加到您的 WebFormRoute(s)。例如,您可以创建一个 IRouteConstraint 实现来匹配 RouteDirection.IncomingRequest,然后使用它来确保该路由被服务器生成的路由(例如 ActionLink)忽略,但仍被客户端生成的请求使用。比如:

        public class IncomingOnlyRouteConstraint: IRouteConstraint
        {
            public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
            {
                if (routeDirection == RouteDirection.IncomingRequest)
                {
                    return true;
                }
                return false;
            }
        }
        

        然后将约束添加到您的路线:

        routes.Add("AspxRoute", new Route("Upload/New", null, 
                                    new RouteValueDictionary() { {"WebFormsConstraint", new IncomingOnlyRouteConstraint()} }, 
                                    new WebFormRouteHandler<Page>("~/Uploads.aspx")));
        

        当然,您可能更喜欢添加自己的约束样式,这对实现它的路由有很大的限制,但这只是您可以解决问题的一种方法的示例。

        【讨论】:

        • 谢谢,我用这个答案解决了我的另一个问题。
        • 太棒了!正是我想要的!
        【解决方案5】:

        试试:

        <%=Html.RouteLink("Test", "Default", new {controller = "Controller", action = "Action"})%>
        

        使用 RouteLink 而不是 ActionLink 允许您指定要使用的路由,在本例中是默认 MVC 路由映射,而不是您添加的自定义路由。

        【讨论】:

        • 您好,谢谢。我知道 RouteLink 有效,但这只是一点点不便!所有的魔线。为什么 ActionLink 不起作用。
        • 它只包含比 ActionLink 多一个字符串,而您最初的问题是“如何构建正确的 url?”。之所以需要这样做,是因为您的 WebFormRouteHandler 提供了“有效”路由匹配,并且由于它是在 RouteTable 中的默认路由之前添加的,因此它首先被返回。但无论如何,我添加了另一个答案,可能更符合您的喜好。
        猜你喜欢
        • 1970-01-01
        • 2011-09-02
        • 2010-09-22
        • 1970-01-01
        • 1970-01-01
        • 2021-05-01
        • 2011-10-27
        • 1970-01-01
        • 2011-11-24
        相关资源
        最近更新 更多