ASP.NET MVC 路由规则XML化

转自:http://www.aspxcs.net/HTML/1017491546.html

 ASP.NET MVC 路由规则XML化【附源码示例】

浏览量: 1 作者:佚名 来源:互联网

由于MVC框架发展不久,还有很多不足的地方。其中关于路由规则配置这一块问题比较大。首先路由规则是在全局配置问价 Global.asax 的 Application_Start()事件中注册的。【源码示例下载

  1. public static void RegisterRoutes(RouteCollection routes) 
  2.     { 
  3.         routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
  4.         routes.MapRoute( 
  5.             "User",                                              // Route name 
  6.             "{controller}/{action}/{id}",                           // URL with parameters 
  7.             new { controller = "User", action = "Show", id = "0" }  // Parameter defaults 
  8.         ); 
  9.     } 
  10.     protected void Application_Start() 
  11.     { 
  12.         RegisterRoutes(RouteTable.Routes); 
  13.     } 

默认硬编码的方式使得以后可维护程度大大降低。MVC 1.0 似乎没有提供很好的基于配置文件的路由规则设置。所以只好自己实现了。直到写这篇文章时,才找到了一个比较好的解决方案。

以下是 自定义的XML 格式

  1. <!--默认规则--> 
  2. <MapRoute name="Default" url="{controller}/{action}"> 
  3.   <Params> 
  4.     <Item key="controller" default="Article"/> 
  5.     <Item key="action" default="Index"/> 
  6.   </Params> 
  7. </MapRoute> 
  8.  
  9. <!--显示新闻列表的路由规则--> 
  10. <MapRoute name="ShowArticleList" url="{controller}/{action}/{typeId}/{pageIndex}/{pageSize}"> 
  11.   <Params> 
  12.     <Item key="controller" default="Article"/> 
  13.     <Item key="action" default="Index"/> 
  14.     <Item key="typeId" default="1"/> 
  15.     <Item key="pageIndex" default="1"/> 
  16.     <Item key="pageSize" default="10"/> 
  17.   </Params> 
  18. </MapRoute> 
  19.  
  20. MapRoutes> 

一下是全部代码

  1. /* *********************************************** 
  2.  * 作者 :汤晓华/tension 任何转载请务必保留此头部信息 版权所有 盗版必究 
  3.  * Email:tension1990@hotmail.com  
  4.  * 描述 : 
  5.  * 创建时间:2010-3-9 15:17:26 
  6.  * 修改历史: 
  7.  * ***********************************************/ 
  8. using System; 
  9. using System.Collections.Generic; 
  10. using System.Linq; 
  11. using System.Text; 
  12. using System.Web.Routing; 
  13. using System.Web.Mvc; 
  14. using System.Xml.Linq; 
  15. using Microsoft.CSharp; 
  16. using System.CodeDom.Compiler; 
  17.  
  18. namespace Tension.Mvc 
  19.     public static class RouteHelper 
  20.     { 
  21.         /// <summary> 
  22.         /// 从XML文件中注册路由规则 
  23.         /// </summary> 
  24.         /// <param name="routes"></param> 
  25.         /// <param name="cfgFile"></param> 
  26.         public static void Register(this RouteCollection routes, string cfgFile) 
  27.         { 
  28.  
  29.             IList<Route> Routes = GetRoutes(cfgFile); 
  30.  
  31.             foreach (var item in Routes) 
  32.             { 
  33.                 //路由规则对象 
  34.                 object obj = CreateObjectFormString(item.ToString(), item.Name); 
  35.                 routes.MapRoute( 
  36.                        item.Name,               // Route name 
  37.                        item.Url,                // URL with parameters 
  38.                         obj                     // Parameter defaults 
  39.                    ); 
  40.  
  41.             } 
  42.         } 
  43.  
  44.         /// <summary> 
  45.         ///  从XML文件中注册路由规则 默认文件为网站根目录下MapRoute.config 
  46.         /// </summary> 
  47.         /// <param name="routes"></param> 
  48.         public static void Register(this RouteCollection routes) 
  49.         { 
  50.             Register(routes, string.Format("{0}//MapRoute.config", Tension.ServerInfo.GetRootPath())); 
  51.         } 
  52.  
  53.  
  54.         /// <summary> 
  55.         /// 从string动态创建类对象 
  56.         /// </summary> 
  57.         /// <param name="codeString"></param> 
  58.         /// <param name="className"></param> 
  59.         /// <returns></returns> 
  60.         private static object CreateObjectFormString(string codeString, string className) 
  61.         { 
  62.             CSharpCodeProvider ccp = new CSharpCodeProvider(); 
  63.             CompilerParameters param = new CompilerParameters(new string[] { "System.dll" }); 
  64.             CompilerResults cr = ccp.CompileAssemblyFromSource(param, codeString); 
  65.             Type type = cr.CompiledAssembly.GetType(className); 
  66.             return type.GetConstructor(System.Type.EmptyTypes).Invoke(null); 
  67.         } 
  68.  
  69.         /// <summary> 
  70.         /// 从XML文件中解析路由规则 
  71.         /// </summary> 
  72.         /// <param name="configFile"></param> 
  73.         /// <returns></returns> 
  74.         private static IList<Route> GetRoutes(string configFile) 
  75.         { 
  76.             StringBuilder sb = new StringBuilder(); 
  77.  
  78.  
  79.             Console.WriteLine(sb.ToString()); 
  80.             IList<Route> Routes = new List<Route>(); 
  81.  
  82.             XElement xe = XElement.Load(configFile); 
  83.  
  84.             #region MyRegion 
  85.             foreach (var item in xe.Elements("MapRoute")) 
  86.             { 
  87.  
  88.                 //名称属性 
  89.                 XAttribute xaName = item.Attribute("name"); 
  90.                 if (xaName == null || string.IsNullOrEmpty(xaName.Value)) 
  91.                 { 
  92.                     throw new ArgumentNullException("name!说明:路由配置文件中某规则缺少name属性或name属性的值为空字符串"); 
  93.                 } 
  94.  
  95.                 //URL属性 
  96.                 XAttribute urlName = item.Attribute("url"); 
  97.                 if (urlName == null || string.IsNullOrEmpty(urlName.Value)) 
  98.                 { 
  99.                     throw new ArgumentNullException("url!说明:路由配置文件中某规则缺少url属性或url属性的值为空字符串"); 
  100.                 } 
  101.  
  102.  
  103.                 Dictionary<stringstring> DictParams = new Dictionary<stringstring>(); 
  104.  
  105.  
  106.  
  107.                 #region MyRegion 
  108.                 foreach (var pItem in item.Element("Params").Elements("Item")) 
  109.                 { 
  110.                     XAttribute itemKey = pItem.Attribute("key"); 
  111.                     if (itemKey == null || string.IsNullOrEmpty(itemKey.Value)) 
  112.                     { 
  113.                         throw new ArgumentNullException("Item->key!说明:路由配置文件中某规则缺少Item->key属性或Item->key属性的值为空字符串"); 
  114.                     } 
  115.  
  116.                     XAttribute itemDefault = pItem.Attribute("default"); 
  117.                     if (itemDefault == null || string.IsNullOrEmpty(itemDefault.Value)) 
  118.                     { 
  119.                         throw new ArgumentNullException("Item->default!说明:路由配置文件中某规则缺少Item->default属性或Item->default属性的值为空字符串"); 
  120.                     } 
  121.                     DictParams.Add(itemKey.Value, itemDefault.Value); 
  122.                 } 
  123.                 #endregion 
  124.  
  125.                 Routes.Add(new Route() { Name = xaName.Value, Url = urlName.Value, Params = DictParams }); 
  126.  
  127.  
  128.             } 
  129.             #endregion 
  130.  
  131.             return Routes; 
  132.         } 
  133.     } 
  134.  
  135.  
  136.     /// <summary> 
  137.     /// 路由规则 
  138.     /// </summary> 
  139.     public class Route 
  140.     { 
  141.         public string Name { getset; } 
  142.         public string Url { getset; } 
  143.         public Dictionary<stringstring> Params { getset; } 
  144.  
  145.         /// <summary> 
  146.         /// 重写ToString 方法 产生需要动态代码段 
  147.         /// </summary>  
  148.         /// <returns></returns> 
  149.         public override string ToString() 
  150.         { 
  151.             StringBuilder sb = new StringBuilder(); 
  152.             sb.AppendFormat("public class {0}", Name); 
  153.             sb.Append("{"); 
  154.             foreach (var item in Params) 
  155.             { 
  156.                 sb.AppendFormat("public string {0}", item.Key); 
  157.                 sb.Append("{get{return /""); 
  158.                 sb.Append(item.Value); 
  159.                 sb.Append("/";}} "); 
  160.             } 
  161.  
  162.             sb.Append("}"); 
  163.             return sb.ToString(); 
  164.         } 
  165.     } 

在实现过程中遇到的最大问题就是 参数列表的动态装载 看一下以下代码

  1. routes.MapRoute( 
  2.                "User",                                              // Route name 
  3.                "{controller}/{action}/{id}",                           // URL with parameters 
  4.                new { controller = "User", action = "Show", id = "0" }  // Parameter defaults 
  5.            ); 

这是硬编码实现的路由规则注册
其中 第三个参数(new { controller = "User", action = "Show", id = "0" } ) 是一个匿名对象
该对象如何动态构建成了难题。(才疏学浅)
尝试着传入一个 Dictionary<K,T> 但是没有用,ASP.NET 解析这个参数的时候是以反射形式读取的对象属性。
后来想到了使用代码段 在运行时动态创建对象。

我们将类似代码段

  1. public class Default{public string controller{get{return "Article";}} public str 
  2. ing action{get{return "Index";}} public string id{get{return "0";}} public strin 
  3. g page{get{return "1";}} public string size{get{return "10";}} } 

传入方法

  1. private static object CreateObjectFormString(string codeString, string className) 
  2.         { 
  3.             CSharpCodeProvider ccp = new CSharpCodeProvider(); 
  4.             CompilerParameters param = new CompilerParameters(new string[] { "System.dll" }); 
  5.             CompilerResults cr = ccp.CompileAssemblyFromSource(param, codeString); 
  6.             Type type = cr.CompiledAssembly.GetType(className); 
  7.             return type.GetConstructor(System.Type.EmptyTypes).Invoke(null); 
  8.         } 

即可有运行时动态的创建我们需要的参数对象。
以后就可以方便的在XML注册路由了。
public static void Register(this RouteCollection routes) 对 RouteCollection 对象添加了扩展方法
引入对应的命名空间后就方便的注册了。

改进后的注册方法

  1. public static void RegisterRoutes(RouteCollection routes) 
  2.         { 
  3.             routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
  4.  
  5.         } 
  6.  
  7.         protected void Application_Start() 
  8.         { 
  9.  
  10.             RegisterRoutes(RouteTable.Routes); 
  11.  
  12.             //执行RouteCollection的扩展方法 用来注册XML文件中的路由配置信息 
  13.             RouteTable.Routes.Register(); 
  14.         } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值