Warum rendert Html.ActionLink "? Length = 4"


305

Ich bin sehr verwirrt darüber, warum dieser Code

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

Ergebnisse in diesem Link:

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

Der hidefocusTeil ist das, was ich erreichen wollte, aber woher kommt der ?Length=4?


4
Dieses Verhalten tritt auch bei den Methoden Html.BeginForm () auf.
Jonathon Watney

Antworten:


326

Die Länge = 4 stammt aus einem Versuch, ein Zeichenfolgenobjekt zu serialisieren. Ihr Code führt diese ActionLinkMethode aus:

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

Dies nimmt ein stringObjekt "Home" für routeValues, das von der MVC-Installation nach öffentlichen Eigenschaften durchsucht wird, um sie in Routenwerte umzuwandeln. Im Fall eines stringObjekts ist die einzige öffentliche Eigenschaft Length, und da mit einem Length-Parameter keine Routen definiert werden, werden der Eigenschaftsname und der Wert als Abfragezeichenfolgenparameter angehängt. Wenn Sie dies von einer Seite ausführen, die nicht darauf ist HomeController, wird wahrscheinlich ein Fehler über eine fehlende AboutAktionsmethode ausgegeben. Versuchen Sie Folgendes:

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

@Blah_Blah heutzutage benutze ich das überhaupt nicht, schreibe lieber meine eigenen <a> -Tags und benutze nur Url.Action ("Action", "Controller")
roryf

@roryf keine Sorge ... dies wurde in einer Codeüberprüfung als Best Practices verwendet, sie haben das Datum nicht überprüft. Es sollte wirklich eine Möglichkeit geben, den Stapelüberlauf nach Datum zu filtern ...
THBBFT

Gute Antwort. Nur um dies hinzuzufügen, geschieht dies aus demselben Grund auch auf Html.BeginRouteForm. Html.BeginRouteForm ("Route", "Aktion", FormMethod.Post)) Sollte Html.BeginRouteForm ("Route", neu {action = "AgentSignUp"}, FormMethod.Post) sein, das die seltsame Länge
beseitigt

Passiert auch mit Url.Action(). Der Wechsel von Url.Action("Action", "Controller", new { area = "" })bis Url.Action("Action", new { controller = "Controller", area = "" })hält die Eigenschaft Länge angezeigt werden , .
John Washam

Um solche Situationen zu vermeiden, können Sie jederzeit angeben, welche Parameter Sie übergeben, z. Html.ActionLink("About", "About", "Home", routeValues: null, htmlAttributes: new { hidefocus = "hidefocus" })
B

195

Ich habe dies gelöst, indem ich dem vierten Parameter vor der anonymen Deklaration ( new {}) eine Null hinzugefügt habe, damit die folgende Methodenüberladung verwendet wird: (linkText, actionName, controllerName, routeValues, htmlAttributes):

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

Dies ist die beste Antwort, wenn Sie keine Verknüpfung zwischen Bereichen herstellen. Wenn Sie den Bereich für den Link angeben müssen, müssen Sie die routeValues ​​mit controllerund angeben area, damit die Length-Eigenschaft nicht in der URL angezeigt wird .
John Washam

@ JohnWasham Eigentlich müssen Sie den Controller nicht im, routeValuessondern nur im Bereich angeben . Zum Beispiel:Html.ActionLink("About", "About", "Home", new {@area = "Admin"}, new { hidefocus = "hidefocus" })
Epiplon

1
@epiplon, der Grund, warum ich den Controller so spezifiziere, ist ActionLink, dass MVC einen seltsamen Length=xParameter am Ende der URL einfügt, wenn Sie htmlAttributes nicht als letztes Argument von angeben . Wenn Sie dies beispielsweise auf eine Seite setzen und dann die Quelle Ihrer Seite anzeigen, werden Sie sehen, was ich meine: @Html.ActionLink("About", "About", "Home", new { area = "Admin" }, new { hidefocus = "hidefocus" }) @Html.ActionLink("About", "About", "Home", new { area = "Admin" }) Wenn Sie den controllerEintrag in das routeValuesFeld einfügen, wird er niemals Length=xin die URL eingefügt.
John Washam

@epiplon, Sie brauchen auch nicht zu verwenden , @in @area = "Admin", nur damit Sie wissen.
John Washam

88

Sie haben vergessen, den Parameter HTMLAttributes hinzuzufügen.

Dies funktioniert ohne Änderungen:

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

Ich weiß nicht, warum das bei mir nicht funktioniert. Ich habe es mit "new {hidefocus =" "}" versucht. Und das funktioniert bei mir.
Naredla Nithesh Reddy

28

Die Parameter für ActionLink sind nicht korrekt. Es wird versucht, den Wert "Home" anstelle des anonymen Typs als Routenwert zu verwenden.

Ich glaube, Sie müssen nur new { }oder nullals letzten Parameter hinzufügen .

BEARBEITEN: Lesen Sie den Beitrag erneut und stellen Sie fest, dass Sie wahrscheinlich null als vorletzten Parameter und nicht als letzten angeben möchten.


1
Übrigens sollten sie eine Methode entfernen, da es nicht möglich ist, sie zu verwenden!
Marc Climent

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

Dies nimmt die Überladung auf: Zeichenfolge linkText, Zeichenfolge actionName, Zeichenfolge controllerName, Object routeValues, Object htmlAttributes


3

Bitte verwenden Sie die rechtsüberladene Methode mit fünf (5) Parametern. Beispiel:

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

Das Hinzufügen von null nach dem Namen des Controllers war in meinem Fall hilfreich.
Munam Yousuf

Dies ist praktisch die gleiche Antwort wie die Antwort von @ Jesse mit dem zusätzlichen Bonus, dass sie die Ajax-Version abdeckt, was nicht das ist, was das OP verlangt hat, aber es hängt mit demselben Problem zusammen.
Gcoulby

2

Entfernen Sie einfach "Home" (Name des Controllers), damit der Code wie folgt lautet:

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

1

Mit Attributnamen:

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

0

Wie Jonathon Watney in einem Kommentar betonte, gilt dies auch für

Html.BeginForm ()

Methoden. In meinem Fall befand ich mich in einer Create.cshtml , die auf die Post-Anfrage des entsprechenden Controllers + Create-Aktion abzielte , und hatte

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

Dabei wurde der Formularaktion beim Rendern der Querystring "? Length = 6" hinzugefügt . Ausgehend von Roryfs genehmigter Antwort und der Erkenntnis, dass die Stringlänge von "Create" 6 beträgt, habe ich dies schließlich gelöst, indem ich die explizite Aktionsspezifikation entfernt habe:

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

0

Möglicherweise hatten andere das gleiche Problem und müssen einen Klassenwert über HTMLAttributes parm angeben. Hier ist meine Lösung:

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


0

Die Suche nach einer Antwort auf meine Frage hat mich hier gelandet. Im Grunde ist es die Auswahl der richtigen Überlastung, @Html.ActionLink Geben Sie hier die Bildbeschreibung ein die zählt.
Ich habe eine Überlastung ausgewählt, die ( ohne die letzte null ) nicht vorhanden war und MVCkeine solche Überlastung aufwies, was zu einer falschen URL führte, wie sie im OP erwähnt wurde.

Eine persönliche Anmerkung: Sie können useanonyme Typen nicht , dass Sie eine der overloads- verwenden können welche Sie existieren nicht? - stellen Sie sicher: es muss definiert werden!
- Kam hier in Zeiten von MVC 5.2

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.