Why does Html.ActionLink render "?Length=4"

Viewed 94517

I'm VERY confused as to why this code

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

results in this link:

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

The hidefocus part is what I was aiming to achieve, but where does the ?Length=4 come from?

12 Answers

The Length=4 is coming from an attempt to serialize a string object. Your code is running this ActionLink method:

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

This takes a string object "Home" for routeValues, which the MVC plumbing searches for public properties turning them into route values. In the case of a string object, the only public property is Length, and since there will be no routes defined with a Length parameter it appends the property name and value as a query string parameter. You'll probably find if you run this from a page not on HomeController it will throw an error about a missing About action method. Try using the following:

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

The parameters to ActionLink are not correct, it's attempting to use the "Home" value as a route value, instead of the anonymous type.

I believe you just need to add new { } or null as the last parameter.

EDIT: Just re-read the post and realized you'll likely want to specify null as the second last parameter, not the last.

This worked fine

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

added new { area = "" }.

As Jonathon Watney pointed out in a comment, this also goes for

Html.BeginForm()

methods. In my case, I was in a Create.cshtml targeting the post request of the corresponding controller + Create action and had

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

which was adding the querystring "?Length=6" to the form action when rendered. Hinted by roryf's approved answer and realizing the string length of "Create" is 6, I finally solved this by removing the explicit action specification:

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

Perhaps others had the same issue and need to supply a class value via HTMLAttributes parm. Here's my solution:

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

Search for an answer to my question landed me here, basically it's the selection of correct overload of @Html.ActionLink enter image description here which matters.
I was selecting an overload which didn't exist, (without the last null), and MVC had no such overload, resulting in a false URL something like the OP mentioned.

A personal note: you can use anonymous types doesn't mean you can use any of the overloads- which do not exist? - make certain: it has to be defined!
- Came here in times of MVC 5.2

Related