Perché Html.ActionLink esegue il rendering "? Lunghezza = 4"


305

Sono MOLTO confuso sul perché questo codice

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

risultati in questo link:

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

La hidefocusparte è ciò che intendevo ottenere, ma da dove ?Length=4viene?


4
Questo comportamento si verifica anche con i metodi Html.BeginForm ().
Jonathon Watney,

Risposte:


326

La lunghezza = 4 proviene da un tentativo di serializzare un oggetto stringa. Il tuo codice esegue questo ActionLinkmetodo:

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

Questo prende un stringoggetto "Home" per routeValues, che l'idraulico MVC cerca le proprietà pubbliche trasformandole in valori di route. Nel caso di un stringoggetto, l'unica proprietà pubblica è Lengthe poiché non ci saranno route definite con un parametro Length, il nome e il valore della proprietà vengono aggiunti come parametro della stringa di query. Probabilmente scoprirai che se lo esegui da una pagina non presente HomeController, verrà generato un errore relativo a un Aboutmetodo di azione mancante . Prova a utilizzare quanto segue:

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

@Blah_Blah in questi giorni non lo uso affatto, preferisco scrivere i miei tag <a> e semplicemente usare Url.Action ("Action", "Controller")
roryf

@roryf non preoccuparti ... questo è stato usato in una recensione di codice come best practice, non hanno controllato la data. Dovrebbe esserci davvero un modo per filtrare lo stackoverflow per data ...
THBBFT

Bella risposta. Solo per aggiungere questo succede anche su Html.BeginRouteForm per lo stesso motivo. Html.BeginRouteForm ("Route", "Action", FormMethod.Post)) Dovrebbe essere Html.BeginRouteForm ("Route", nuovo {action = "AgentSignUp"}, FormMethod.Post) che elimina la strana cosa della lunghezza
radm4

Succede anche con Url.Action(). La modifica da Url.Action("Action", "Controller", new { area = "" })a Url.Action("Action", new { controller = "Controller", area = "" })impedisce la visualizzazione della proprietà Lunghezza.
John Washam,

Per evitare questo tipo di situazione, puoi sempre specificare quali parametri stai passando, come:Html.ActionLink("About", "About", "Home", routeValues: null, htmlAttributes: new { hidefocus = "hidefocus" })
Epiplon

195

Il modo in cui ho risolto questo è stato l'aggiunta di un null al quarto parametro prima della dichiarazione anonima ( new {}) in modo che utilizzi il seguente sovraccarico del metodo: (linkText, actionName, controllerName, routeValues, htmlAttributes):

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

Questa è la risposta migliore se non stai collegando tra le aree. Se è necessario specificare l'area per il link, si avrebbe bisogno di specificare le routeValues con il controllere il areadi mantenere la proprietà lunghezza da presentarsi nell'URL.
John Washam,

@JohnWasham In realtà, non è necessario specificare il controller nell'area routeValuesma solo nell'area. Ad esempio:Html.ActionLink("About", "About", "Home", new {@area = "Admin"}, new { hidefocus = "hidefocus" })
Epiplon

1
@epiplon, il motivo per cui specifico il controller in questo modo è perché se non includi mai htmlAttributes come ultimo argomento di ActionLink, MVC includerà uno strano Length=xparametro alla fine dell'URL. Ad esempio, inseriscilo in una pagina, quindi visualizza l'origine della tua pagina e vedrai cosa intendo: @Html.ActionLink("About", "About", "Home", new { area = "Admin" }, new { hidefocus = "hidefocus" }) @Html.ActionLink("About", "About", "Home", new { area = "Admin" }) Ma se inserisci la controllervoce in routeValues, non inserirà mai Length=xl'URL.
John Washam,

@epiplon, anche voi non c'è bisogno di utilizzare @in @area = "Admin", solo così sai.
John Washam,

88

Hai dimenticato di aggiungere il parametro HTMLAttributes.

Questo funzionerà senza alcuna modifica:

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

Non lo so, perché questo non ha funzionato per me. Ho provato con "new {hidefocus =" "}", E questo funziona per me.
Naredla Nithesh Reddy,

28

I parametri di ActionLink non sono corretti, sta tentando di utilizzare il valore "Home" come valore di route, anziché il tipo anonimo.

Credo che devi solo aggiungere new { }o nullcome ultimo parametro.

EDIT: rileggi il post e ti rendi conto che probabilmente vorrai specificare null come il secondo ultimo parametro, non l'ultimo.


1
A proposito, dovrebbero rimuovere un metodo in quanto non è possibile usarlo!
Marc Climent,

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

Questo richiederà il sovraccarico: string linkText, string actionName, string controllerName, Object routeValues, Object htmlAttributes


3

Si prega di utilizzare il metodo corretto sovraccarico con cinque (5) parametri. Esempio:

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

l'aggiunta di null dopo il nome del controller è stata utile nel mio caso.
Munam Yousuf il

Questa è effettivamente la stessa risposta della risposta di @ Jesse con l'aggiunta del bonus che copre la versione Ajax, che non è quella richiesta dall'OP, ma è collegata allo stesso problema.
gcoulby,

2

Rimuovi "Home" (nome del controller) in modo che il codice sia:

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

1

Con i nomi degli attributi:

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

0

Come ha sottolineato Jonathon Watney in un commento, questo vale anche per

Html.BeginForm ()

metodi. Nel mio caso, mi trovavo in un file Create.cshtml indirizzato alla richiesta di post del controller corrispondente + azione Crea e avevo

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

che stava aggiungendo il querystring "? Lunghezza = 6" all'azione del modulo quando eseguito il rendering. Accennato dalla risposta approvata di roryf e realizzando che la lunghezza della stringa di "Crea" è 6, ho finalmente risolto rimuovendo la specifica dell'azione esplicita:

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

0

Forse altri hanno avuto lo stesso problema e devono fornire un valore di classe tramite HTMLAttributes parm. Ecco la mia soluzione:

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


0

Cercare una risposta alla mia domanda mi ha portato qui, in fondo è la selezione del sovraccarico corretto di @Html.ActionLink inserisci qui la descrizione dell'immagine cui conta.
Stavo selezionando un sovraccarico che non esisteva, ( senza l' ultimo null ), e MVCnon avevo tale sovraccarico, risultando in un falso URL qualcosa come l'OP menzionato.

Una nota personale : puoi usetipi anonimi non significa che puoi usare nessuno dei sovraccarichi che non esistono? - rendere certo: esso deve essere definito!
- È venuto qui in tempi di MVC 5.2

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.