ASP.NET MVC Url.Action将当前路由值添加到生成的url

我在这里几次看到过这个问题,但他们都没有任何可接受的答案:

ASP.NET MVC @ Url.Action包含当前的路由数据
ASP.NET MVC隐式添加路由值

基本上我有一个名为Group的动作方法的Controller,它有一个超载,它不接收任何参数并显示一个元素列表,另一个接收一个id并显示该组的详细信息。

如果我做这样的事情:

Url.Action("Group", "Groups");

从网站的主页(/)返回一个像这样的网址:

"mysite.com/Groups/Group"

这是好的现在,如果该网站的当前地址是/ Groups / Group / 1并且我调用了相同的方法

Url.Action("Group", "Groups");

返回的url是这样的:

"mysite.com/Groups/Group/1"

它在生成URL时自动为当前页面添加路由的值。 即使我这样生成URL:

Url.Action("Group", "Groups", null);

因此明确指定我不想要任何路由值,所生成的URL是相同的。 为了得到我想要的地址,我必须明确地将路由值设置为空字符串,如下所示:

Url.Action("Group", "Groups", new {id=""});

这将生成以下网址:

"mysite.com/Groups/Group"

我的问题是,为什么会发生这种情况? 如果我没有设置任何路由值,则不应将它们添加到生成的URL中。


如果您没有明确设置它们,Url.Action将重新使用当前的请求参数。 它是在出站url匹配算法中设计的。 在生成url的过程中查找路由数据参数时,参数取自:

1)明确提供了值

2)来自当前请求的值

3)默认

按照上面指定的顺序。

对于路由的出站匹配算法很复杂,所以最好是为请求显式设置所有参数,就像你在例子中做的那样


我的应用程序显式设置路径值,并不想从当前请求中获得魔法值。 我想完全控制。

我做了一个扩展,与我的路由库集合共存。 因此,单个RouteValueDictionary参数。 (请参阅我的路线库评论底​​部)

这里我在生成一个url之前从请求中删除任何路由值。

(注意:对于array.contains ignorecase部分,请参阅:如何使Array.Contains在字符串数组上不区分大小写?)

public static string Action(this UrlHelper helper, 
                            RouteValueDictionary routeValues)
{
    RemoveRoutes(helper.RequestContext.RouteData.Values);

    string url = helper.Action(routeValues["Action"].ToString(), routeValues);
    return url;
}

public static void RemoveRoutes(RouteValueDictionary currentRouteData)
{
    List<string> keyList = new List<string>(currentRouteData.Keys);

    string[] ignore = new[] { "Area", "Controller", "Action" };
    foreach (string key in keyList)
    {
        if (!ignore.Contains(key, StringComparer.CurrentCultureIgnoreCase))
            currentRouteData.Remove(key);
    }
}

我有使用RemoveRoutes方法的Form和ActionLink扩展方法。 我的mvc库中没有任何助手使用不是我创建的扩展方法的方法。 因此,在生成URL之前,所有路由数据都会被清除。

为了参考,我使用了AttributeRouting。 以下是我的路线库中的一条路线的示例。

public static RouteValueDictionary DisplayNews(int newsId)
{
    RouteValueDictionary route = new RouteValueDictionary();
    route["Area"] = _area;
    route["Controller"] = _controller;
    route["Action"] = "DisplayNews";
    route["newsId"] = newsId;
    return route;
}

所以当我阅读objectbox的答案时,我想我将不得不修改我的代码中的几个链接。 然后我尝试添加一个默认路由,省略了解决问题的默认参数:

routes.MapRoute(
    "ArtistArtworkDefPage",
    "Artist/{username}/Artwork",
    new
    {
        controller = "Artist",
        action = "Artwork",
        page = 1
    }
);

routes.MapRoute(
    "ArtistArtwork",
    "Artist/{username}/Artwork/{page}",
    new
    {
        controller = "Artist",
        action = "Artwork",
        page = 1
    },
    new { page = @"d+" }
);
链接地址: http://www.djcxy.com/p/49983.html

上一篇: ASP.NET MVC Url.Action adds current route values to generated url

下一篇: Asp.net mvc routing : ActionLink return an url with parameters in querystring