添加非mvc路由时Html.ActionLink构造错误链接 [英] Html.ActionLink construct wrong link when a non-mvc route is added

查看:30
本文介绍了添加非mvc路由时Html.ActionLink构造错误链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an application here with a mix of webform and mvc. I specify the routing as below

        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 网络表单页面.

So that virtual path to "Upload/New" actually maps to an aspx webform page.

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

But my problem is that Html.ActionLink("Test", "Controller", "Action") now renders

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

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

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

Having looked at the MVC source code, I understand that it is because ActionLink calls to RouteCollection.GetVirtualPath(requestContext, routeName, mergedRouteValues), where routeName is left to null. And somehow this defaults to use the AspxRoute route to construct the url. I tried to added another route before "AspxRoute", but it seems it always defaults to the non-mvc routehandler one.

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

How does RouteCollection.GetVirtualPath behave when routeName is null? And why is it behaving this way for my case?

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

How do I construct a correct url? Do I need to write a new Htmlhelper extension?

干杯

推荐答案

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

An alternative option would be to add a custom constraint to your WebFormRoute(s). For example, you could create an implementation of IRouteConstraint to match RouteDirection.IncomingRequest, then use it to ensure the route is ignored by Server-Generated routes (such as ActionLink) but still used by client-generated requests. Something like:

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

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

And then add the constraint to your route:

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

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

Of course you may prefer to add your own style of constraint, this one is quite limiting on the route that implements it, but it's just an example of one way you could resolve the issue.

这篇关于添加非mvc路由时Html.ActionLink构造错误链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆