Me gustaría crear babosas personalizadas para páginas en mi CMS, para que los usuarios puedan crear sus propias URL de SEO (como Wordpress).ASP.NET MVC: enrutamiento de babosas personalizadas sin afectar el rendimiento
Solía hacer esto en los frameworks de Ruby on Rails y PHP "abusando" de la ruta 404. Se llamó a esta ruta cuando no se pudo encontrar el controlador solicitado, lo que me permitió enrutar al usuario a mi controlador de páginas dinámicas para analizar el slug (desde donde los redirigí al 404 real si no se encontró ninguna página). De esta forma, solo se consultó a la base de datos para verificar el slug solicitado.
Sin embargo, en MVC, la ruta catch-all solo se invoca cuando la ruta no se ajusta a la ruta predeterminada de /{controller}/{action}/{id}
.
todavía ser capaz de analizar las babosas personalizados he modificado el archivo 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();
}
}
Esto resuelve mi problema, pero requiere la tabla Pages
estar plenamente consultada para cada solicitud. Debido a que un método de show sobrecargado (public ViewResult Show(Page p)
) no funcionó, también tengo que recuperar la página una segunda vez porque solo puedo pasar la identificación de la página.
- ¿Hay una mejor manera de resolver mi problema?
- ¿Es posible pasar el objeto Página a mi método Show en lugar de la ID de página?
¿No se inicializó solo al inicio de la aplicación? Solo en una nota al margen: 'db.Dispose();'? Editar: Lo siento, no estaba leyendo tu pregunta muy bien. ¿Quizás podría poner las páginas en la memoria caché global? – Silvermind
¡Gracias por apuntar en la dirección correcta! La función solo se llama al inicio. Creo que lo estaba viendo como si fuera un lenguaje interpretado (como PHP). Considerando que el código solo se ejecuta al inicio, creo que el impacto en el rendimiento es insignificante. Sin embargo, todavía no estoy seguro de si este es el camino a seguir, o si esto ya se puede lograr mediante el uso de la funcionalidad incorporada. También me pregunto si es posible pasar el Modelo en lugar de la ID (Pregunta nº 2). – christiaanderidder