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?

Mein Alter Ego
quelle
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" })
roryf
quelle
@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" })
Manuel Castro
quelle
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)
Jesse Rose
quelle
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.


quelle
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

user2254436
quelle
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" }))
Omveer singh maurya
quelle
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" })
Fil
quelle
1

Mit Attributnamen:

 @Html.ActionLink(linkText: "SomeText", actionName: "SomeAction", controllerName: "SomeControllerName", routeValues: new { parameterName = parameterValue}, htmlAttributes: null)
nützlichBee
quelle
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()
      ...
    }
Frederik Struck-Schøning
quelle
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" })

Taersious
quelle
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

Irf
quelle