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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (38)

基本上我有一个名为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之前从请求中删除任何路由值。

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

扫码关注云+社区