Dlaczego Html.ActionLink renderuje „? Length = 4”

305

Jestem BARDZO zdezorientowany, dlaczego ten kod

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

wyniki w tym linku:

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

hidefocusCzęścią jest to, czego dąży do osiągnięcia, ale skąd ?Length=4pochodzi?

My Alter Ego
źródło
4
To zachowanie występuje również w przypadku metod Html.BeginForm ().
Jonathon Watney

Odpowiedzi:

326

Długość = 4 pochodzi z próby serializacji obiektu łańcuchowego. Twój kod to uruchamiaActionLink metodę:

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

Pobiera to stringobiekt „Home” dla routeValues, który instalator MVC szuka właściwości publicznych, zamieniając je w wartości trasy. W przypadku stringobiektu jedyną właściwością publiczną jest Length, a ponieważ nie będzie zdefiniowanych tras za pomocą parametru Długość, dołącza nazwę i wartość właściwości jako parametr ciągu zapytania. Prawdopodobnie przekonasz się, że jeśli uruchomisz to ze strony, która nie jest na HomeControllerniej, zgłosi błąd dotyczący braku Aboutmetody działania. Spróbuj użyć następujących opcji:

Html.ActionLink("About", "About", new { controller = "Home" }, new { hidefocus = "hidefocus" })
roryf
źródło
@Blah_Blah w dzisiejszych czasach w ogóle tego nie używam, wolę pisać własne tagi <a> i po prostu używać Url.Action („Action”, „Controller”)
roryf
@roryf nie martw się ... zostało to użyte w recenzji kodu jako najlepsza praktyka, nie sprawdzili daty. Naprawdę powinien istnieć sposób na filtrowanie
przepełnienia stosu
Świetna odpowiedź. Wystarczy dodać, że dzieje się tak również na Html.BeginRouteForm z tego samego powodu. Html.BeginRouteForm („Route”, „Action”, FormMethod.Post)) Powinien to być Html.BeginRouteForm („Route”, new {action = "AgentSignUp"}, FormMethod.Post), który pozbywa się dziwnej długości
radm4
Zdarza się również z Url.Action(). Zmiana z Url.Action("Action", "Controller", new { area = "" })na Url.Action("Action", new { controller = "Controller", area = "" })powoduje, że właściwość Length nie jest wyświetlana.
John Washam,
Aby uniknąć tego rodzaju sytuacji, zawsze możesz określić, jakie parametry przekazujesz, na przykład:Html.ActionLink("About", "About", "Home", routeValues: null, htmlAttributes: new { hidefocus = "hidefocus" })
Epiplon,
195

Rozwiązałem to poprzez dodanie wartości null do czwartego parametru przed deklaracją anonimową ( new {}), aby używał następującego przeciążenia metody: (linkText, actionName, controllerName, routeValues, htmlAttributes):

Html.ActionLink("About", "About", "Home", null, new { hidefocus = "hidefocus" })
Manuel Castro
źródło
To najlepsza odpowiedź, jeśli nie łączysz się między obszarami. Jeśli musisz określić obszar dla łącza, musisz określić routeValues ​​za pomocą controlleri, areaaby właściwość Length nie była wyświetlana w adresie URL.
John Washam,
@JohnWasham W rzeczywistości nie musisz określać kontrolera routeValuestylko w obszarze. Na przykład:Html.ActionLink("About", "About", "Home", new {@area = "Admin"}, new { hidefocus = "hidefocus" })
Epiplon,
1
@epiplon, powód, dla którego określam taki kontroler, jest taki, że jeśli kiedykolwiek nie podasz htmlAttributes jako ostatniego argumentu ActionLink, MVC będzie zawierać dziwny Length=xparametr na końcu adresu URL. Na przykład, umieść to na stronie, a następnie wyświetl źródło swojej strony, a zobaczysz, co mam na myśli: @Html.ActionLink("About", "About", "Home", new { area = "Admin" }, new { hidefocus = "hidefocus" }) @Html.ActionLink("About", "About", "Home", new { area = "Admin" }) Ale jeśli umieścisz controllerwpis w routeValues, nigdy nie będzie on wstawiał Length=xadresu URL.
John Washam
@epiplon, również nie musisz używać @ w @area = "Admin", tylko dlatego, że wiesz.
John Washam,
88

Zapomniałeś dodać parm HTMLAttributes.

Będzie to działać bez żadnych zmian:

Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" },null)
Jesse Rose
źródło
Nie wiem, dlaczego to dla mnie nie zadziałało. Próbowałem z „new {hidefocus =" "}", i to działa dla mnie.
Naredla Nithesh Reddy
28

Parametry ActionLink są niepoprawne, próbuje użyć wartości „Home” jako wartości trasy, zamiast typu anonimowego.

Uważam, że wystarczy dodać new { }lubnull jako ostatni parametr.

EDYCJA: Po prostu ponownie przeczytaj post i zdałeś sobie sprawę, że prawdopodobnie będziesz chciał określić null jako drugi ostatni parametr, a nie ostatni.


źródło
1
BTW Powinny usunąć jedną metodę, ponieważ nie można jej użyć!
Marc Climent,
5
Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" }, new { })

Spowoduje to przeciążenie: string linkText, string actionName, string controllerName, Object routeValues, Object htmlAttributes

użytkownik2254436
źródło
3

Łagodnie używaj odpowiednio przeciążonej metody z pięcioma (5) parametrami. Przykład:

@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
źródło
dodanie null po nazwie kontrolera było pomocne w moim przypadku.
Munam Yousuf
Jest to w rzeczywistości ta sama odpowiedź, co odpowiedź @ Jesse z dodatkowym bonusem, że obejmuje ona wersję Ajax, która nie jest tym, o co poprosił PO, ale jest związana z tym samym problemem.
gcoulby
2

Wystarczy usunąć „Dom” (nazwa kontrolera), aby kod był:

Html.ActionLink("About", "About", new { hidefocus = "hidefocus" })
Fil
źródło
1

Z nazwami atrybutów:

 @Html.ActionLink(linkText: "SomeText", actionName: "SomeAction", controllerName: "SomeControllerName", routeValues: new { parameterName = parameterValue}, htmlAttributes: null)
przydatne
źródło
0

Jak zauważył Jonathon Watney w komentarzu, dotyczy to również

Html.BeginForm ()

metody W moim przypadku byłem w pliku Create.cshtml kierującym żądanie postu odpowiedniego kontrolera + akcja Create i miałem

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

który dodaje kwerendę „? Długość = 6” do akcji formularza podczas renderowania. Na podstawie zatwierdzonej odpowiedzi roryfa i uświadomienia sobie, że długość ciągu „Utwórz” wynosi 6, w końcu rozwiązałem to, usuwając jawną specyfikację akcji:

using (Html.BeginForm()) {
      @Html.AntiForgeryToken()
      ...
    }
Frederik Struck-Schøning
źródło
0

Być może inni mieli ten sam problem i musieli podać wartość klasy poprzez HTMLAttributes parm. Oto moje rozwiązanie:

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

Tętniący
źródło
0

Poszukiwanie odpowiedzi na moje pytanie wylądowało tutaj, w zasadzie wybór właściwego przeciążenia, @Html.ActionLink wprowadź opis zdjęcia tutaj który ma znaczenie.
Ja wybierając przeciążenia, które nie istnieje, ( bez ostatni null ), iMVC nie miał takiego przeciążenia, w wyniku fałszywego adresu URL coś podobnego PO wymienione.

Osobista uwaga: możesz useanonimowych typów nie oznacza, że ​​możesz użyć któregoś z przeciążeń - które nie istnieją? - mieć pewność: to ma być zdefiniowana!
- Przybył tutaj w czasach MVC 5.2

Irf
źródło