ASP.NET MVC CMS数据库的dynamic路由
基本上我有一个使用ASP.NET MVC构build的CMS后端,现在我正在转到前端站点,并且需要能够根据input的路由从我的cms数据库加载页面。
因此,如果用户inputdomain.com/students/information,MVC会查看页表,看看是否存在具有与学生/信息匹配的永久链接的页面,如果是,则redirect到页面控制器,然后加载页面数据库中的数据并将其返回到视图以进行显示。
到目前为止,我试图抓住所有的路线,但它只适用于两个网段,所以/学生/信息,但不/学生/信息/秋天。 我无法find任何关于如何完成这个任务的东西,所以我尽pipe在这里find并开放源代码ASP.NET MVC cms并parsing代码。
这里是目前为止的路线configuration,但我觉得有一个更好的方法来做到这一点。
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" } ); }
如果任何人都可以指引我如何从数据库中加载CMS页面,最多有三个URL段,并且仍然能够加载具有预定义的控制器和操作的核心页面。
您可以使用约束来决定是否覆盖默认路由逻辑。
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; } }
在路由定义中使用它,
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 } );
现在,如果你在“Page”控制器中有一个“索引”操作,
public ActionResult Index(string permalink) { //load the content from db with permalink //show the content with view }
- 所有的URL都会被第一条路由所捕获,并受到约束的validation。
- 如果永久链接存在于数据库中,URL将由页面控制器中的索引动作处理。
- 如果不是,约束将失败,url将回退到默认路由(我不知道如果你有任何其他控制器在项目中,你将如何决定你的404逻辑)。
编辑
为了避免在Page
控制器的Index
操作中重新查询cms页面,可以使用HttpContext.Items
字典,就像
在约束中
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;
那么在行动中,
public ActionResult Index(string permalink) { var page = HttpContext.Items["cmspage"] as CMSPage; //show the content with view }
希望这可以帮助。