2009-09-24 72 views
7

我在这里有一个应用程序,其中混合了webform和mvc。我指定路由如下当添加非mvc路由时,Html.ActionLink构造错误的链接

 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 
     ); 

因此,“Upload/New”的虚拟路径实际上映射到aspx webform页面。

但我的问题是,Html.ActionLink( “测试”, “控制器”, “行动”)现在呈现

/上传/新?控制器=控制器&行动=行动

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

RouteCollection.GetVirtualPath如何在routeName为空时表现?为什么它对我的情况如此呢?

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

干杯

回答

3

尝试:

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

使用,而不是ActionLink的RouteLink允许您指定要使用的路径,在这种情况下是相对于自定义一个默认MVC路由映射你已经添加了。

+0

感谢你好。我知道RouteLink的作品,但这只是一点点的不便!所有的魔术弦。为什么ActionLink不起作用。 – 2009-11-19 18:10:15

+0

它只包含一个比ActionLink更多的字符串,你原来的问题是“我如何构造一个正确的url?”。之所以有这个必要,是因为你的WebFormRouteHandler提供了一个“有效的”路由匹配,并且它是在RouteTable的默认路由之前添加的,因此它首先被返回。但无论如何,我已经添加了另一个可能更符合你的喜好的答案。 – 2009-11-20 14:51:58

6

另一个选择是将自定义约束添加到您的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"))); 

当然,你可能更愿意增加自己的约束的风格,这个人是相当限制实现它的路线,但这只是您解决问题的一种方式。

+0

谢谢,我用这个答案来解决我的另一个问题。 – JTew 2011-09-01 01:51:56

+0

太棒了!正是我正在寻找的! – gsobocinski 2013-01-20 16:49:46

+1

我很遗憾,我只有一个满意的答复。 – 2013-02-22 03:47:20

2

另请确保您的默认路由是路由表中的最后一个条目。这是另一个简单的方法,可以结束你所获得的那种html动作链接。

+0

从这么久以前的问题仍然可以得到答案:-) 如果你看看我附加的代码,它是路由表中的最后一个条目。 MVC.net已经走过了一段很长的路,也许这一切都改变了,我不知道! – 2011-04-08 17:45:28

1

我遇到了同样的情况,路由正常工作“入站”,但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的()的调用结束忽略的路线。希望这可以帮助别人!

1

力的路线默认为无控制器:

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