上一篇介绍了 公文流转系统 的实现,本篇介绍下MVC下动态自定义路由的实现。
在典型的CMS系统中,通常需要为某个栏目指定个友链地址,通过指定友链地址,该栏目的地址更人性化、方便记忆,也有利用于搜索引擎优化。
但在MVC中,通常需要在应用程序启动时注册路由规则,该路由规则又通常和控制器进行了关联,也就是某个地址通常情况下都是有对应的控制器进行处理的。但在MVC中如何做到自定义动态路由,以便能在运行时通过某个控制器处理一些运行时动态设定的Url地址呢?
方法当然是有的:
1、首先实现一个动态路由约束条件类:
该类用于判断指定的路由地址是否满足特定的路由规则,当然该规则需要在后面进行注册才会生效。
1 public class CmsUrlConstraint : IRouteConstraint 2 { 3 public CmsUrlConstraint() 4 { 5 6 } 7 /// <summary> 8 /// 动态查询数据库,判断当前请求地址是否满足约定 9 /// </summary> 10 /// <param name="httpContext"></param> 11 /// <param name="route"></param> 12 /// <param name="parameterName"></param> 13 /// <param name="values"></param> 14 /// <param name="routeDirection"></param> 15 /// <returns></returns> 16 public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, 17 RouteDirection routeDirection) 18 { 19 if (values[parameterName] != null) 20 { 21 //此为请求的友链地址参数 22 var permalink = values[parameterName].ToString(); 23 24 var dbcontext = new YbObjectContext("YbRapidSolution"); 25 //根据友链地址参数,查找栏目,存在则表示匹配成功 26 var page = dbcontext.Set<CmsColumn>() 27 .Where(p => p.Permalink == permalink).FirstOrDefault(); 28 if (page != null) 29 { 30 //匹配成功进行数据传值 31 HttpContext.Current.Items["cmspage"] = page; 32 return true; 33 } 34 return false; 35 } 36 return false; 37 } 38 }
2、然后注册路由CmsColumnRoute和CmsRoute,指定上述满足约束条件的地址该由哪个真实的控制器进行处理:
1 public static void RegisterRoutes(RouteCollection routes) 2 { 3 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 4 //routes.IgnoreRoute("{UEditor/controller}.ashx{*pathInfo}"); 5 routes.IgnoreRoute("{resource}.ashx/{*pathInfo}"); 6 7 routes.MapRoute( 8 name: "CmsColumnRoute", 9 url: "{*permalink}", 10 defaults: new { controller = "Home", action = "ColumnPage", id = UrlParameter.Optional }, 11 constraints: new { permalink = new CmsUrlConstraint() } 12 ); 13 routes.MapRoute( 14 name: "CmsRoute", 15 url: "{action}/{*permalink}", 16 defaults: new { controller = "Home", action = "ColumnPage", id = UrlParameter.Optional }, 17 constraints: new { permalink = new CmsUrlConstraint() } 18 ); 19 20 routes.MapRoute( 21 name: "Default", 22 url: "{controller}/{action}/{id}", 23 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional} 24 ); 25 }
运行原理:
1、输入特定地址
2、系统通过CmsUrlConstraint类的Match方法查询数据库,如该地址和某个栏目中设定的友链地址一致,则表示匹配成功
3、如匹配成功,则通过注册路由时设定的Controller和Action进行后续处理并返回View。
具体过程如下:
实现效果如下:
1、运行过程中可随意指定该栏目的地址:
2、然后通过指定的地址可访问该页面,但我们并没有专门实现News的控制器: