浅析ASP.NET MVC路由规则XML化的方法

开发 后端
本文由作者为大家介绍ASP.NET MVC路由规则XML化的方法,希望对大家的开发有所帮助。

本文主要针对的是ASP.NET MVC路由规则的问题,作者本次所研究的是ASP.NET MVC路由规则XML,希望那个通过本文能对大家有所帮助。

最近由于工作关系,重新回顾了ASP.NET MVC的1.0 版本。2.0版本还没有研究。

由于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. <?xml version="1.0" encoding="utf-8" ?>    
  2. <MapRoutes>  
  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. <MapRoute name="ShowArticleList" url="{controller}/{action}/{typeId}/{pageIndex}/{pageSize}">    
  10.   <Params>    
  11.     <Item key="controller" default="Article"/>    
  12.     <Item key="action" default="Index"/>    
  13.     <Item key="typeId" default="1"/>    
  14.     <Item key="pageIndex" default="1"/>    
  15.     <Item key="pageSize" default="10"/>    
  16.   </Params>    
  17. </MapRoute>    
  18.  </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.  namespace Tension.Mvc    
  18.  {    
  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.              IList<Route> Routes = GetRoutes(cfgFile);     
  29.              foreach (var item in Routes)    
  30.             {    
  31.                  //路由规则对象    
  32.                  object obj = CreateObjectFormString(item.ToString(), item.Name);    
  33.                  routes.MapRoute(    
  34.                         item.Name,               // Route name    
  35.                         item.Url,                // URL with parameters    
  36.                         obj                     // Parameter defaults    
  37.                     );     
  38.              }    
  39.          }    
  40.          /// <summary>    
  41.          ///  从XML文件中注册路由规则 默认文件为网站根目录下MapRoute.config    
  42.          /// </summary>    
  43.          /// <param name="routes"></param>    
  44.          public static void Register(this RouteCollection routes)    
  45.         {    
  46. Register(routes, string.Format("{0}\\MapRoute.config", Tension.ServerInfo.GetRootPath()));    
  47.         }      
  48.          /// <summary>    
  49.         /// 从string动态创建类对象    
  50.         /// </summary>    
  51.          /// <param name="codeString"></param>    
  52.          /// <param name="className"></param>    
  53.         /// <returns></returns>    
  54.          private static object CreateObjectFormString(string codeString, string className)    
  55.          {    
  56.              CSharpCodeProvider ccp = new CSharpCodeProvider();    
  57.              CompilerParameters param = new CompilerParameters(new string[] { "System.dll" });    
  58.              CompilerResults cr = ccp.CompileAssemblyFromSource(param, codeString);    
  59.              Type type = cr.CompiledAssembly.GetType(className);    
  60.              return type.GetConstructor(System.Type.EmptyTypes).Invoke(null);    
  61.          }    
  62.  /// <summary>    
  63. /// 从XML文件中解析路由规则    
  64. /// </summary>    
  65.  /// <param name="configFile"></param>    
  66. /// <returns></returns>    
  67. private static IList<Route> GetRoutes(string configFile)    
  68. {    
  69. StringBuilder sb = new StringBuilder();    
  70. Console.WriteLine(sb.ToString());    
  71. IList<Route> Routes = new List<Route>();    
  72. XElement xe = XElement.Load(configFile);    
  73. #region MyRegion    
  74. foreach (var item in xe.Elements("MapRoute"))    
  75.  {    
  76. 名称属性    
  77. XAttribute xaName = item.Attribute("name");    
  78. if (xaName == null || string.IsNullOrEmpty(xaName.Value))    
  79. {    
  80. throw new ArgumentNullException("name!说明:路由配置文件中某规则缺少name属性或name属性的值为空字符串");    
  81.  }    
  82. //URL属性    
  83. XAttribute urlName = item.Attribute("url");    
  84.  if (urlName == null || string.IsNullOrEmpty(urlName.Value))    
  85. {    
  86.  throw new ArgumentNullException("url!说明:路由配置文件中某规则缺少url属性或url属性的值为空字符串");    
  87.   }    
  88. Dictionary<stringstring> DictParams = new Dictionary<stringstring>();    
  89.  #region MyRegion    
  90.  foreach (var pItem in item.Element("Params").Elements("Item"))    
  91.   {    
  92.  XAttribute itemKey = pItem.Attribute("key");    
  93. if (itemKey == null || string.IsNullOrEmpty(itemKey.Value))    
  94.  {    
  95. throw new ArgumentNullException("Item->key!说明:路由配置文件中某规则缺少Item->key属性或Item->key属性的值为空字符串");    
  96.   }    
  97.  XAttribute itemDefault = pItem.Attribute("default");    
  98. if (itemDefault == null || string.IsNullOrEmpty(itemDefault.Value))    
  99. {    
  100. throw new ArgumentNullException("Item->default!说明:路由配置文件中某规则缺少Item->default属性或Item->default属性的值为空字符串");    
  101.  }    
  102.  DictParams.Add(itemKey.Value, itemDefault.Value);    
  103.  }    
  104.  #endregion    
  105. Routes.Add(new Route() { Name = xaName.Value, Url = urlName.Value, Params = DictParams });    
  106. }    
  107.  #endregion    
  108.  return Routes;    
  109.     }    
  110.     }    
  111.  /// <summary>    
  112.  /// 路由规则    
  113.  /// </summary>    
  114.  public class Route    
  115.  {    
  116.  public string Name { getset; }    
  117. public string Url { getset; }    
  118. public Dictionary<stringstring> Params { getset; }    
  119.  /// <summary>    
  120. /// 重写ToString 方法 产生需要动态代码段    
  121. /// </summary>     
  122.  /// <returns></returns>    
  123.  public override string ToString()    
  124.  {    
  125.  StringBuilder sb = new StringBuilder();    
  126.  sb.AppendFormat("public class {0}", Name);    
  127. sb.Append("{");    
  128.  foreach (var item in Params)    
  129.  {    
  130. sb.AppendFormat("public string {0}", item.Key);    
  131. sb.Append("{get{return \"");    
  132. sb.Append(item.Value);    
  133. sb.Append("\";}} ");    
  134.   }    
  135. sb.Append("}");    
  136.  return sb.ToString();    
  137.  }    
  138.    }    
  139. }  

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

  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);   

即可有运行时动态的创建我们需要的参数对象。

以后就可以方便的在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. protected void Application_Start()   
  6.  {   
  7. RegisterRoutes(RouteTable.Routes);   
  8.  //执行RouteCollection的扩展方法 用来注册XML文件中的路由配置信息   
  9. RouteTable.Routes.Register();   
  10.  } 

代码下载地址

/tandly/MvcRouteHelper.rar

原文标题:ASP.NET MVC路由规则XML化

链接:http://www.cnblogs.com/tandly/archive/2010/03/10/1682301.html

【编辑推荐】

  1. 专访微软MVP衣明志:走进ASP.NET MVC 2框架开发
  2. 详解ASP.NET MVC 2中强类型HTML辅助方法
  3. ASP.NET MVC 2 RC版全新发布 增强HTML控制
  4. 详解ASP.NET MVC 2自定义验证
  5. 详解ASP.NET MVC对表进行通用的增删改 
     
责任编辑:彭凡 来源: 博客园
相关推荐

2009-07-31 12:43:59

ASP.NET MVC

2009-07-23 14:31:20

ASP.NET MVC

2009-07-22 15:02:02

ASP.NET MVC

2009-04-08 09:58:07

ASP.NET MVCTempData框架

2009-07-20 10:33:02

ASP.NET MVC

2009-07-22 09:11:02

Action方法ASP.NET MVC

2009-08-04 17:28:45

Apache支持ASP

2014-08-21 09:31:06

路由

2009-07-24 10:55:00

asp.net mvc

2009-07-23 15:11:43

XML Web服务方法ASP.NET

2009-09-24 09:26:22

ASP.NET MVC

2009-09-10 09:50:47

ASP.NET MVC

2009-07-27 15:34:11

MembershipASP.NET

2009-07-27 09:29:38

ASP.NET中Jav

2009-07-30 13:45:40

ASP.NET开发模式MVC模式

2009-11-02 10:15:53

ASP.NET MVC

2009-07-27 10:18:12

TypeResolveASP.NET

2009-07-24 10:53:51

ASP.NET实现静态

2009-07-20 16:09:39

2009-07-24 13:41:15

ASP.NET AJA
点赞
收藏

51CTO技术栈公众号