ASP.NET MVC Anteprima 4: Interrompi Url.RouteUrl() ecc.utilizzando i parametri esistenti
-
09-06-2019 - |
Domanda
Ho un'azione come questa:
public class News : System.Web.Mvc.Controller
{
public ActionResult Archive(int year)
{
/ *** /
}
}
Con un percorso del genere:
routes.MapRoute(
"News-Archive",
"News.mvc/Archive/{year}",
new { controller = "News", action = "Archive" }
);
L'URL su cui mi trovo è:
News.mvc/Archive/2008
Ho un modulo in questa pagina come questo:
<form>
<select name="year">
<option value="2007">2007</option>
</select>
</form>
L'invio del modulo dovrebbe andare su News.mvc/Archive/2007 se nel modulo è selezionato "2007".
Ciò richiede che l'attributo del modulo "azione" sia "News.mvc/Archive".
Tuttavia, se dichiaro un modulo come questo:
<form method="get" action="<%=Url.RouteUrl("News-Archive")%>">
viene visualizzato come:
<form method="get" action="/News.mvc/Archive/2008">
Qualcuno può farmi sapere cosa mi sto perdendo?
Soluzione
Hai un paio di problemi, credo.
Innanzitutto, il tuo percorso non ha un valore predefinito per "anno", quindi l'URL "/News.mvc/Archive" in realtà non è valido per scopi di routing.
In secondo luogo, ti aspetti che i valori del modulo vengano visualizzati come parametri di percorso, ma non è così che funziona l'HTML.Se utilizzi un modulo semplice con una selezione e un invio, i tuoi URL finiranno per avere "?anno=2007" alla fine.Questo è proprio il modo in cui i moduli del metodo GET sono progettati per funzionare in HTML.
Quindi devi giungere ad una conclusione su ciò che è importante.
- Se vuoi che l'utente sia in grado di selezionare qualcosa dal menu a discesa e questo modifica l'URL di invio, dovrai utilizzare Javascript per raggiungere questo obiettivo (intercettando l'invio del modulo e formulando l'URL corretto).
- Se sei d'accordo con /News.mvc/Archive?year=2007 come URL, dovresti rimuovere completamente il designatore {year} dal percorso.Puoi comunque lasciare il parametro "int year" sulla tua azione, poiché i valori del modulo popoleranno anche i parametri del metodo dell'azione.
Altri suggerimenti
Penso di aver capito perché: il percorso include {anno}, quindi lo faranno sempre anche i percorsi generati..
Se qualcuno può confermarlo?
Soluzione
Ok, ecco la soluzione (grazie a Brad per avermi guidato lì).
1) Richiedi un valore predefinito nel percorso:
routes.MapRoute(
"News-Archive",
"News.mvc/Archive/{year}",
new { controller = "News", action = "Archive", year = 0 }
);
2) Aggiungi un reindirizzamento per analizzare i parametri GET come se fossero segmenti URL.
public ActionResult Archive(int year)
{
if (!String.IsNullOrEmpty(Request["year"]))
{
return RedirectToAction("Archive", new { year = Request["year"] });
}
}
3) Assicurati di avere il codice di reindirizzamento per i parametri Richiesta Prima qualsiasi codice per reindirizzare le voci dell'anno "predefinito".cioè.
public ActionResult Archive(int year)
{
if (!String.IsNullOrEmpty(Request["year"]))
{
return RedirectToAction("Archive", new { year = Request["year"] });
}
if (year == 0)
{
/* ... */
}
/* ... */
}
3) Specificare esplicitamente il valore predefinito per anno nella chiamata Url.RouteUrl():
Url.RouteUrl("News-Archive", new { year = 0 })