ASP.NET查找路由表RouteTable中路由名等信息的方法
??????? 10年前使用的.NET 2.0需要升級了,要讀讀.NET Framework 4.5方面的技術書了。最近在看《精通ASP.NET 4.5》(第5版)中有關的路由技術時,發現列出路由表中映射的虛擬路徑比較容易,但要找出映射的物理文件路徑和路由名就比較麻煩。看到該書后面章節時,找到了路由表映射的物理文件文件路徑。于是,使用Bing滿世界查找,終于在一個論壇中找到了一個可行的方法。
??????? 方法思路是:RouteTable.Routes的類型是RouteCollection,該類派生自Collection<RouteBase>,其中包含了一個不公開的Dictionary<string, RouteBase>字典成員,該字典就是一個路由名作為Key的路由字典。如何獲得該字典成員是問題的關鍵。解決方法是:該字典成員使用了私有字段_namedMap(不知道原文作者是如何知道的,見本文的后記),通過反射技術可以獲得字段成員。
1、路由配置(測試用)
??????? 下面的代碼是一個路由表的設置情況,為簡單見,把配置代碼寫在了全局應用程序類Global的隱藏代碼文件Global.asax.cs中。
??????? 下面代碼是ListRouteItems.aspx的網頁部分代碼。
??????? 下面代碼是ListRouteItems.aspx的代碼隱藏文件ListRouteItems.aspx.cs,其中包含了獲得Dictionary<string, RouteBase>的代碼和自定義結構體RouteItem。代碼中可以看出,RouteCollection類的_namedMap私有字段保存了路由表字典(基本信息)。
using System.Collections.Generic; using System.Web.Routing; using System.Reflection;namespace Test {public partial class ListRouteItems : System.Web.UI.Page{public IEnumerable<RouteItem> GetRouteItems(){var routeCollection = GetRouteCollection(); // 獲得路由名為Key的字典foreach (var route in System.Web.Routing.RouteTable.Routes){Route r = route as Route;if (r != null){string name = GetRouteName(routeCollection, route); // 獲得路由名PageRouteHandler p = r.RouteHandler as PageRouteHandler; // 獲得映射的物理文件路徑yield return new RouteItem { Name = name, MappedPath = r.Url, PhysicalPath = p.VirtualPath };}}}private Dictionary<string, RouteBase> GetRouteCollection(){var routes = System.Web.Routing.RouteTable.Routes;var namedMapField = routes.GetType().GetField("_namedMap", BindingFlags.NonPublic | BindingFlags.Instance);var collection = namedMapField.GetValue(routes) as Dictionary<string, RouteBase>;return collection;}private string GetRouteName(Dictionary<string, RouteBase> collection, RouteBase route){foreach (var item in collection){if (item.Value == route){return item.Key;}}return "(null)";}}public struct RouteItem{public string Name { get; set; }public string MappedPath { get; set; }public string PhysicalPath { get; set; }} } 4、ListRouteItems.aspx運行圖??????? 下圖是網頁程序運行情況。
??????? 結合上面網頁圖和代碼ListRouteItems.aspx.cs知道,路由表中路由名null和""空串相同,且沒有保存在RouteCollection的_nameMap字典中。
后記
?????? 仔細思考了為何原文作者知道RouteCollection有一個_namedMap字段的問題。進一步,即如何破解MS中類型定義未公開的秘密?答案是使用反射技術。例如如下代碼就可以大致了解RouteCollection的字段成員,進而估計出該類有一個Dictionary<string, RouteBase>字典成員。
Type type = typeof(System.Web.Routing.RouteCollection); FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); foreach (var fi in fields) {Console.WriteLine(fi.Name + "," + fi.FieldType.UnderlyingSystemType); }總結
以上是生活随笔為你收集整理的ASP.NET查找路由表RouteTable中路由名等信息的方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 宝宝起名测试,你的名字多少分?
- 下一篇: matlab大圆航线,基于MATLAB和