Routing ASP.NET MVC per un singolo sito controller
-
05-07-2019 - |
Domanda
Sto cercando di creare un sito semplice. Fondamentalmente ha un controller Home
controller.
Questo controller ha un'azione Index
accetta un string
come argomento (che è una directory) e usa quella 'directory' per fare il suo lavoro.
Non riesco a capire come creare un generico catch all route che invierà tutti gli URL a questa azione.
Potrebbe esistere qualsiasi combinazione di URL e qualsiasi cosa oltre il nome di dominio dovrebbe essere la stringa.
http://<domain>/2008
http://<domain>/2008/09
http://<domain>/2008/09/Fred
Qualcuno sa come farlo? Andrebbe anche bene se tutti i valori fossero passati come un elenco.
Esiste un modo migliore per farlo?
Soluzione
Prova questo:
routes.MapRoute(
"Default", "{*path}",
new { controller = "Home", action = "Index" }
);
E il controller:
public class HomeController : Controller {
public ActionResult Index(string path) {
return View();
}
}
Altri suggerimenti
Il mio primo pensiero è che è una "cattiva idea". Se puoi prendere qualsiasi cosa che possono lanciarti per un URL, dovrai avere una lista nera (o una whitelist). Ci sono così tante aperture. Un modo migliore sarebbe quello di precisare esplicitamente quei percorsi e il modo in cui si consentono i parametri e quindi eseguire azioni che si occupano di tali percorsi accettati. Avresti quindi un generico catturare tutto il percorso che reindirizzerebbe a una pagina di errore.
Sembra che tu stia provando a mescolare mele e arance. ASP.NET MVC elimina intenzionalmente l'idea di "pagina". Non c'è davvero alcun motivo per avere directory per vari utenti a meno che non si stia eseguendo una sorta di I / O di file e, in tal caso, può essere astratto per funzionare nel paradigma ASP.NET MVC molto più facilmente di quanto si possa pensare.
In ASP.NET MVC se volevi variare le informazioni che stai cercando in base alla stringa passata (proprio come la stringa che hai passato), ecco un modo "sicuro" per farlo:
Metodo n. 1 - Tre percorsi, tre azioni, nomi diversi
routes.MapRoute(
"YearOnly",
"{year}",
new { controller = "Index", action = "ShowByYear" },
new { year = @"\d{4}" }
);
routes.MapRoute(
"YearAndMonth",
"{year}/{month}",
new { controller = "Index", action = "ShowByYearAndMonth" },
new { year = @"\d{4}", month = @"\d{2}" }
);
routes.MapRoute(
"YearMonthAndName",
"{year}/{month}/{name}",
new { controller = "Index", action = "ShowByYearMonthAndName" },
new { year = @"\d{4}", month = @"\d{2}" }
);
E poi useresti i valori di route passati nelle tue azioni del controller per determinare come vedono i dati:
ShowByYear(string year)
{
//Return appropriate View here
}
ShowByYearAndMonth(string year, string month)
{
//Return appropriate View here
}
ShowByYearMonthAndName(string year, string month, string name)
{
//Return appropriate View here
}
Metodo # 2 - Metodo suggerito
routes.MapRoute(
"YearOnly",
"{year}",
new { controller = "Index", action = "Show" },
new { year = @"\d{4}" }
);
routes.MapRoute(
"YearAndMonth",
"{year}/{month}",
new { controller = "Index", action = "Show" },
new { year = @"\d{4}", month = @"\d{2}" }
);
routes.MapRoute(
"YearMonthAndName",
"{year}/{month}/{name}",
new { controller = "Index", action = "Show" },
new { year = @"\d{4}", month = @"\d{2}", name = "" }
);
Show(string year)
{
//
}
Show(string year, string month)
{
//Return appropriate View here
}
Show(string year, string month, string name)
{
//Return appropriate View here
}
Il bello di questo approccio è che MapRoute
gestisce l'analisi dell'URL; e tiene fuori il riff-raff. È quindi possibile impostare un percorso generale che genera solo un errore. Preferiresti fare un po 'di analisi sul lato del percorso con regex
rispetto al tuo controller (secondo me).
Questo lo mantiene fino a tre azioni sovraccariche e consente un codice più pulito e più "MVC".