Rutas dinámicas desde la base de datos para ASP.NET MVC CMS

Básicamente, tengo un back-end CMS que construí usando ASP.NET MVC y ahora me estoy moviendo al sitio frontend y necesito poder cargar páginas desde mi base de datos cms, de acuerdo con la ruta ingresada.

Entonces, si el usuario ingresa a domain.com/students/information, MVC miraría en la tabla de páginas para ver si existe una página que tenga un enlace permanente que coincida con estudiantes / información, de ser así redirigiría al controlador de página y luego cargaría la página datos de la base de datos y devolverlos a la vista para su visualización.

Hasta ahora he intentado tener una ruta de atrapar todo, pero solo funciona para dos segmentos de URL, entonces / students / information, pero no / students / information / fall. No puedo encontrar nada en línea sobre cómo lograr esto, así que pensé en preguntar aquí, antes de encontrar y abrir código ASP.NET MVC cms y analizar el código.

Esta es la configuración de ruta que tengo hasta ahora, pero creo que hay una mejor manera de hacerlo.

public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // Default route to handle core pages routes.MapRoute(null,"{controller}/{action}/{id}", new { action = "Index", id = UrlParameter.Optional }, new { controller = "Index" } ); // CMS route to handle routing to the PageController to check the database for the route. var db = new MvcCMS.Models.MvcCMSContext(); //var page = db.CMSPages.Where(p => p.Permalink == ) routes.MapRoute( null, "{*.}", new { controller = "Page", action = "Index" } ); } 

Si alguien puede orientarme en la dirección correcta sobre cómo cargar las páginas de CMS desde la base de datos, con hasta tres segmentos de URL, y aún así poder cargar páginas centrales, que tengan un controlador y una acción predefinidos.

Puede usar una restricción para decidir si se sobrescribe la lógica de enrutamiento predeterminada.

 public class CmsUrlConstraint : IRouteConstraint { public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { var db = new MvcCMS.Models.MvcCMSContext(); if (values[parameterName] != null) { var permalink = values[parameterName].ToString(); return db.CMSPages.Any(p => p.Permalink == permalink); } return false; } } 

úsalo en la definición de ruta como,

 routes.MapRoute( name: "CmsRoute", url: "{*permalink}", defaults: new {controller = "Page", action = "Index"}, constraints: new { permalink = new CmsUrlConstraint() } ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); 

Ahora si tiene una acción ‘Index’ en ‘Page’ Controller como,

 public ActionResult Index(string permalink) { //load the content from db with permalink //show the content with view } 
  1. todas las URL serán atrapadas por la primera ruta y serán verificadas por la restricción.
  2. si el enlace permanente existe en db, la URL se manejará mediante acción de índice en el controlador de la página.
  3. de lo contrario, la restricción fallará y la url volverá a la ruta predeterminada (no sé si tiene otros controladores en el proyecto y cómo va a decidir su lógica 404).

EDITAR

Para evitar consultar la página cms en la acción Index en el controlador de Page , se puede usar el diccionario HttpContext.Items , como

en la restricción

 var db = new MvcCMS.Models.MvcCMSContext(); if (values[parameterName] != null) { var permalink = values[parameterName].ToString(); var page = db.CMSPages.Where(p => p.Permalink == permalink).FirstOrDefault(); if(page != null) { HttpContext.Items["cmspage"] = page; return true; } return false; } return false; 

luego en la acción,

 public ActionResult Index(string permalink) { var page = HttpContext.Items["cmspage"] as CMSPage; //show the content with view } 

espero que esto ayude.