为什么Html.ActionLink呈现“?Length = 4”


305

我很困惑为什么这段代码

Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" })

结果在此链接:

<a hidefocus="hidefocus" href="/Home/About?Length=4">About</a>

hidefocus是我要实现的目标,但是它?Length=4从哪里来呢?


4
Html.BeginForm()方法中也会出现此行为。
乔纳森·沃特尼

Answers:


326

Length = 4来自尝试序列化字符串对象。您的代码正在运行此ActionLink方法:

public static string ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues, object htmlAttributes)

string为routeValues 使用对象“ Home”,MVC管道通过该对象搜索公共属性,将其转换为路由值。对于string对象,唯一的公共属性是Length,并且由于将没有使用Length参数定义的路由,因此它将属性名称和值附加为查询字符串参数。您可能会发现,如果从不在HomeController其上的页面运行此命令,则会抛出有关缺少About操作方法的错误。尝试使用以下内容:

Html.ActionLink("About", "About", new { controller = "Home" }, new { hidefocus = "hidefocus" })

@Blah_Blah这些天我根本不使用它,更喜欢编写自己的<a>标签,而仅使用Url.Action(“ Action”,“ Controller”)
roryf

@roryf不用担心...这在代码审查中用作最佳实践,他们没有检查日期。确实应该有一种按日期过滤stackoverflow的方法...
THBBFT 2013年

好答案。出于同样的原因,只是添加它也发生在Html.BeginRouteForm上。Html.BeginRouteForm(“ Route”,“ Action”,FormMethod.Post))应该是Html.BeginRouteForm(“ Route”,new {action =“ AgentSignUp”},FormMethod.Post),它摆脱了奇怪的长度问题
radm4

也会发生Url.Action()。从更改为Url.Action("Action", "Controller", new { area = "" })可以Url.Action("Action", new { controller = "Controller", area = "" })防止显示Length属性。
约翰·沃斯塔姆2014年

为了避免这种情况,您始终可以指定要传递的参数,例如:Html.ActionLink("About", "About", "Home", routeValues: null, htmlAttributes: new { hidefocus = "hidefocus" })
Epiplon 2015年

195

我解决此问题的方法是在匿名声明(new {})之前的第四个参数中添加一个null,以便它使用以下方法重载:(linkText,actionName,controllerName,routeValues,htmlAttributes):

Html.ActionLink("About", "About", "Home", null, new { hidefocus = "hidefocus" })

如果您不在区域之间链接,这是最佳答案。如果您需要指定链接的区域,则需要使用controller和来指定routeValues,area以防止Length属性显示在URL中。
约翰·沃斯塔姆2014年

@JohnWasham实际上,您无需在区域中指定控制器routeValues。例如:Html.ActionLink("About", "About", "Home", new {@area = "Admin"}, new { hidefocus = "hidefocus" })
Epiplon 2015年

1
@epiplon,之所以这样指定控制器是因为,如果您不包含htmlAttributes作为的最后一个参数ActionLink,则MVC将Length=x在URL的末尾包含一个奇怪的参数。例如,将其放在页面上,然后查看页面的源,您将明白我的意思: @Html.ActionLink("About", "About", "Home", new { area = "Admin" }, new { hidefocus = "hidefocus" }) @Html.ActionLink("About", "About", "Home", new { area = "Admin" }) 但是,如果将controller条目放在中routeValues,则永远不会Length=x在URL中。
约翰·沃斯塔姆

@epiplon,你也不需要使用@@area = "Admin",只是让你知道。
约翰·沃瑟姆

88

您忘记添加HTMLAttributes参数。

这将无需任何更改即可工作:

Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" },null)

我不知道,为什么这对我不起作用。我尝试了“ new {hidefocus =“”}“,这对我有用。
Naredla Nithesh Reddy

28

ActionLink的参数不正确,它正在尝试将“ Home”值用作路由值,而不是匿名类型。

我相信您只需要添加new { }null作为最后一个参数。

编辑:只需重新阅读文章,并意识到您可能希望将null指定为倒数第二个参数,而不是最后一个。


1
顺便说一句,他们应该删除一种方法,因为它不可能使用!
马克·克莱门特

5
Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" }, new { })

这将导致重载:字符串linkText,字符串actionName,字符串controllerName,对象routeValues,对象htmlAttributes


3

请使用具有五(5)个参数的右重载方法。例:

@using (@Ajax.BeginForm("Register", "Account", null,
    new AjaxOptions
    {
        HttpMethod = "POST",
        OnSuccess = "OnSuccess",
        OnFailure = "OnFailure",
        OnBegin = "OnBegin",
        OnComplete = "OnComplete"
    }, new { @class = "form-login" }))

在我的情况下,在控制器名称后添加null很有帮助。
Munam Yousuf

实际上,这与@Jesse的答案是相同的答案,并具有覆盖Ajax版本的额外好处,这不是OP要求的,但与同一问题相关。
gcoulby

2

只需删除“ Home”(控制器的名称),使代码为:

Html.ActionLink("About", "About", new { hidefocus = "hidefocus" })

1

具有属性名称:

 @Html.ActionLink(linkText: "SomeText", actionName: "SomeAction", controllerName: "SomeControllerName", routeValues: new { parameterName = parameterValue}, htmlAttributes: null)

0

正如乔纳森·沃特尼(Jonathon Watney)在评论中指出的那样,

Html.BeginForm()

方法。以我为例,我在一个Create.cshtml中定位了相应控制器+ Create操作的发布请求,

using (Html.BeginForm("Create")) {
  @Html.AntiForgeryToken()
  ...
}

呈现时将查询字符串“?Length = 6”添加到表单操作中。在roryf批准的答案的提示下,实现“ Create”的字符串长度为6,我终于通过删除显式操作规范解决了这个问题:

using (Html.BeginForm()) {
      @Html.AntiForgeryToken()
      ...
    }

0

也许其他人也有同样的问题,需要通过HTMLAttributes parm 提供一个值。这是我的解决方案:

@Html.ActionLink("About", "About", new { controller = "Home", area = "" }, new { hidefocus = "hidefocus", @class = "nav-item nav-link" })


0

寻找我的问题的答案使我落到了这里,基本上是选择正确的@Html.ActionLink 在此处输入图片说明 重要内容。
我选择一个重载不存在,(没有最后 null),并MVC没有这样的过载,造成了虚假的URL类似于提到的OP。

个人笔记:您可以use匿名类型并不意味着你可以使用任何overloads-的里面做不存在?- 使某些: 已经被定义!
-在MVC 5.2时代来到这里

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.