asp.net mvc Html.ActionLink()如何保留我不想要的路由值

46

我在视图中有以下的 ActionLink

<%= Html.ActionLink("LinkText", "Action", "Controller"); %>

这会生成以下URL:http://mywebsite.com/Controller/Action

假设我在结尾添加一个ID,像这样:http://mywebsite.com/Controller/Action/53 并且导航到该页面。在该页面上,我拥有了上面指定的标记。现在当我查看它创建的URL时,它看起来像这样:

http://mywebsite.com/Controller/Action/53 (注意ID的添加)

但是我想要去掉ID,并且看起来像最初的样子,就像这个http://mywebsite.com/Controller/Action (注意这里没有ID)

有什么方法可以解决这个问题吗?我不想使用硬编码的URL,因为我的控制器/操作可能会更改。


1
请参阅此工作项,了解微软官方对此问题及解决方法的说明。 - NightOwl888
9个回答

48
解决方案是指定自己的路由值(如下所示的第四个参数)
<%= Html.ActionLink("LinkText", "Action", "Controller", 
    new { id=string.Empty }, null) %>

谢谢你的回答,我需要它用于另一种情况,但你在那个尾部空值方面说得非常准确! - Samurai Ken
这似乎有点笨拙...我需要做同样的事情,但我认为我可能需要像Arnis L在下面发布的那样创建一个新的扩展方法。 - Jiho Han
1
此外,这似乎应该是框架内置功能,因为这种情况经常出现。例如,有一个菜单,您不希望菜单链接包含所有参数,只需包含操作即可。 - Jiho Han
1
我正在使用.NET 4和MVC2,但string.empty无法解决上述问题,而ActionLink仍然保留环境值。 - Muhammad Adeel Zahid

13

听起来你需要注册第二个“仅操作(Action Only)”路由,并使用Html.RouteLink()。首先在应用程序启动时注册一个这样的路由:

routes.MapRoute("ActionOnly", "{controller}/{action}", 
   new { controller = "Home", action = "Index" } );

那么,不要使用ActionLink创建这些链接,而应该使用:

Html.RouteLink("About","ActionOnly")

使用 Html.RouteLink() 可以获得 +1 的好评。这个方法对我很有效 - 你也可以指定 routeValues,这样MVC就会失去当前的操作并返回到索引或其他地方,例如:@Html.RouteLink("取消", "ThisSection_default", new { action = "Index" }) - Jez

10
问题在于内置方法会获取当前 URL 上的输入,同时也会使用你提供的输入。你可以尝试这样做:

问题在于内置方法会获取当前 URL 上的输入,同时也会使用你提供的输入。你可以尝试这样做:

<%= Html.ActionLink("LinkText", "Action", "Controller", new { id = ""}) %>

这应该手动清除id参数。


4

我不知道为什么,但这对我没有起作用(可能是因为Mvc2 RC)。创建了UrlHelper方法 =>

 public static string
            WithoutRouteValues(this UrlHelper helper, ActionResult action,params string[] routeValues)
        {
            var rv = helper.RequestContext.RouteData.Values;
            var ignoredValues = rv.Where(x=>routeValues.Any(z => z == x.Key)).ToList();
            foreach (var ignoredValue in ignoredValues)
                rv.Remove(ignoredValue.Key);
            var res = helper.Action(action);
            foreach (var ignoredValue in ignoredValues)
                rv.Add(ignoredValue.Key, ignoredValue.Value);
            return res;
        }

我曾经遇到过同样的问题(使用MVC2 RTM)。我的路由值叫做“plan”,而最后一个(默认)路由将其添加为“?plan=X”。因此,我在我的“plan”路由值的最后一个(默认)路由中添加了默认值,即“plan=string.Empty”。尽管路由定义没有定义名为“plan”的URL段变量。只要它能正常工作,我就没问题。 - Robert Koritnik
我使用了这个的变体来可靠而优雅地解决这个问题。 - John B

4

我明确将操作名称设置为“Action /”。 这似乎有点像黑客,但这是一个快速解决方案。

@Html.ActionLink("Link Name", "Action/", "Controller")

我也曾经这样做过,链接指向索引,所以我可以只使用“/”作为操作。@Html.ActionLink(“链接名称”,“/”,“控制器”) - Derrick

4
如果您不知道需要显式覆盖哪些值,或者只想避免额外的参数列表,可以使用下面的扩展方法。
<a href="@Url.Isolate(u => u.Action("View", "Person"))">View</a>

这篇博客文章详细介绍了实现细节


简洁明了,非常不错 +1 - T-moty
1
这是一个不太优美的解决方案......但目前为止它仍然是我找到的最佳解决方案。 - Tom Pažourek

3

另一种方法是使用ActionLink(HtmlHelper,String,String,RouteValueDictionary)重载,这样就不需要在最后一个参数中放置null。

<%= Html.ActionLink("Details", "Details", "Product", new RouteValueDictionary(new { id=item.ID })) %>

1
Html.ActionLink的重载在MVC的后续版本中有所改变。在MVC 5及以上版本中,操作方式如下:
@Html.ActionLink("LinkText", "Action", "Controller", new { id = "" }, null)

注意,我将id参数传递为"",HTMLATTRIBUTES参数传递为null。

0
我需要我的菜单链接是动态的。而不是为每个页面实现大量额外的代码和路由,我简单地放弃了HTML助手。
<a href="@(item.websiteBaseURL)/@(item.controller)/@(item.ViewName)">@item.MenuItemName</a>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接