ASP.NET MVC ActionLink: generata Strano URL
-
18-09-2019 - |
Domanda
Perché la seguente chiamata Html.ActionLink
:
Html.ActionLink("Approve", "Advance", new { id = Model.ID, step = StepType.Approve })
generare un URL con parametri di query piuttosto che un URL "riposante", cioè:.
http://localhost/Website/Case/Advance/1?step=Refer
Ho solo il percorso di default registrato, devo percorsi aggiuntivi che possono comprendere ciò che il parametro "StepType" è?
Ho provato ad aggiungere questo percorso in dopo il percorso di default:
routes.MapRoute(
"CaseAdvance",
"{controller}/{action}/{id}/{step}",
new {controller = "Case", action = "Advance", id = "", step = StepType.Refer});
, ma non ha avuto effetto. Aggiunta la nuova registrazione percorso prima il default mi ha dato un errore:
Il dizionario dei parametri contiene un ingresso nullo per il parametro 'id' di tipo non annullabile 'System.Int64' per System.Web.Mvc.ActionResult metodo' Advance (Int64, Website.Core.StepType)' nel 'Website.Controllers.CaseController'. Per fare un parametro opzionale suo tipo dovrebbe essere un tipo di riferimento o Tipo Nullable.
Soluzione
percorso personalizzato cattura troppo al momento
Il tuo eccezione dice soltanto che il vostro itinerario personalizzato sta recuperando qualcosa che non si intendeva che per la cattura. Quindi, se ci sarebbe stata una richiesta al tuo URL principale dell'applicazione:
il percorso personalizzato sarebbe prenderlo. Ed set è di default. E chiamare il vostro azione CaseController.Advance()
. E, naturalmente, un'eccezione, perché id
non è definito.
Mantenete il vostro itinerario personalizzato di fronte al default
Ma si dovrà cambiare il tuo percorso personalizzato o aggiungere vincoli di percorso ad esso in modo sarà effettivamente catturare solo le richieste che è destinata a catturare.
Ma quale cambiamento si dovrebbe fare? Se c'è solo sarà un unico controller che ne ha bisogno di modificarla in:
routes.MapRoute(
"CaseAdvance",
"Case/{action}/{id}/{step}",
new { controller = "Case", action = "Advance", id = "", step = StepType.Refer});
Se non ci sono altri controller un pozzo, si può tenerlo come è stato, è sufficiente aggiungere vincoli:
routes.MapRoute(
"CaseAdvance",
"{controller}/{action}/{id}/{step}",
new { controller = "Case", action = "Advance", id = "", step = StepType.Refer},
new { controller = "Case|Other" });
Se non ci può essere qualsiasi controller, è possibile effettuare un requisito per l'ID di essere numerico:
routes.MapRoute(
"CaseAdvance",
"{controller}/{action}/{id}/{step}",
new { controller = "Case", action = "Advance", id = "", step = StepType.Refer},
new { id = @"\d+" })
In questo caso questo percorso sarà catturare solo le richieste che in realtà hanno un id definito. Come un certo numero di corso.
Si saprà quale si adatta meglio.
Altri suggerimenti
Sì, se non v'è alcun percorso come "{Controller} / {action} / {id} / {step}", quindi il metodo ActionLink sarà semplicemente passare "step" come parametro querystring.
Nel vostro percorso è stato specificato un parametro di stepType ma il vostro passando un parametro chiamato passo.
Le vostre opzioni di ActionLink nomi devono corrispondere ai nomi dei parametri itinerario o si ottiene esattamente ciò che il vostro vedere.
EDIT: Ok, hai cambiato il codice, mentre stavo scrivendo questa risposta !!
Prova a usare RouteLink e vedere se che funziona per voi.
Html.RouteLink("Approve", "CaseAdvance", new { controller = "Case", action = "Advance", id = Model.ID, step = StepType.Approve })
Se chiamando RouteLink produce un link valido sarà almeno significa che il percorso è configurato correttamente.