Vorrei creare slug personalizzati per le pagine nel mio CMS, in modo che gli utenti possano creare i propri URL SEO (come Wordpress).ASP.NET MVC: instradamento di slug personalizzati senza influire sulle prestazioni
Ho usato per fare questo in Ruby su Rails e framework PHP "abusando" della route 404. Questa route è stata chiamata quando non è stato possibile trovare il controller richiesto, consentendo di indirizzare l'utente al mio controller di pagine dinamiche per analizzare lo slug (da dove li ho reindirizzati al 404 reale se non è stata trovata alcuna pagina). In questo modo il database è stato interrogato solo per verificare lo slug richiesto.
Tuttavia, in MVC il percorso catch-all viene chiamato solo quando la rotta non si adatta alla route predefinita di /{controller}/{action}/{id}
.
di essere ancora in grado di analizzare le lumache personalizzati ho modificato il file RouteConfig.cs
:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
RegisterCustomRoutes(routes);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { Controller = "Pages", Action = "Index", id = UrlParameter.Optional }
);
}
public static void RegisterCustomRoutes(RouteCollection routes)
{
CMSContext db = new CMSContext();
List<Page> pages = db.Pages.ToList();
foreach (Page p in pages)
{
routes.MapRoute(
name: p.Title,
url: p.Slug,
defaults: new { Controller = "Pages", Action = "Show", id = p.ID }
);
}
db.Dispose();
}
}
Questo risolve il mio problema, ma richiede la tabella Pages
di essere completamente interrogato per ogni richiesta. Poiché un metodo di visualizzazione sovraccarico (public ViewResult Show(Page p)
) non ha funzionato, devo anche recuperare la pagina una seconda volta perché posso solo passare l'ID della pagina.
- C'è un modo migliore per risolvere il mio problema?
- È possibile passare l'oggetto Pagina al metodo Show anziché all'ID pagina?
Non è inizializzato solo all'avvio dell'applicazione? Solo una nota a margine: 'db.Dispose();'? Edit: Scusa non stavo leggendo la tua domanda molto bene. Forse potresti mettere le pagine nella Global Cache? – Silvermind
Grazie per aver puntato nella giusta direzione! La funzione è infatti solo richiamata all'avvio. Immagino che lo stavo guardando come se fosse un linguaggio interpretato (come PHP). Considerando che questo codice viene eseguito solo all'avvio, suppongo che l'impatto sulle prestazioni sia trascurabile. Tuttavia, non sono ancora sicuro se questa è la strada da percorrere, o se questo è già realizzabile utilizzando la funzionalità integrata. Mi sto anche chiedendo se è possibile passare il modello invece dell'ID (domanda n.2). – christiaanderidder