日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
ASP.NETRouting之“解析URL”功能詳解

經(jīng)??次也┛偷娜丝赡軙?,我是一個喜歡搞點小技巧來實現(xiàn)某個功能的人。例如博客的皮膚,自己花了不少時間定義,也是為了效果豐富一些。當(dāng)然,搞得最多的是從框架或類庫內(nèi)部取出一點小功能來用用,節(jié)省自己開發(fā)的時間。這其實也是一種復(fù)用,尤其是開發(fā)一些“擴(kuò)展”的時候,例如當(dāng)時嘗試為UpdatePanel增加上傳功能,雖然最后的結(jié)果不是很理想,但是大部分的Hack以及前后端的交互是非常成功的(最大的問題在于跨瀏覽器實現(xiàn)iframe通信)。而現(xiàn)在也打算總結(jié)一次這方面的簡單技巧,為以后的文章貢獻(xiàn)點引用資源。

創(chuàng)新互聯(lián)建站是專業(yè)的朗縣網(wǎng)站建設(shè)公司,朗縣接單;提供成都網(wǎng)站設(shè)計、網(wǎng)站制作,網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行朗縣網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊,希望更多企業(yè)前來合作!

ASP.NET Routing中解析URL功能介紹與實現(xiàn)

這次我們想“復(fù)用”的內(nèi)容是ASP.NET URL Routing中“解析URL”的功能。具體一點地說,就是把一個字符串根據(jù)指定的Pattern拆分成鍵/值對的功能。從.NET Reflector反編譯System.Web.Routing.dll的結(jié)果來看,這部分的解析工作是交由RouteParser和ParsedRoute兩個類完成的。這里引用一下相關(guān)的使用代碼,如果您感興趣的話,也可以閱讀它們完整的實現(xiàn):

 
 
 
  1. public class Route
  2. {
  3.     public string Url
  4.     {
  5.         get { ... }
  6.         set
  7.         {
  8.             this._parsedRoute = RouteParser.Parse(value);
  9.             this._url = value;
  10.         }
  11.     }
  12.     public override RouteData GetRouteData(HttpContextBase httpContext)
  13.     {
  14.         string virtualPath = ...
  15.         RouteValueDictionary values = this._parsedRoute.Match(virtualPath, this.Defaults);
  16.         ...
  17.     }
  18.     ...
  19. }

從代碼中可以看出,RouteParser的作用是將一個Pattern(如"{controller}/{action}/{id}")轉(zhuǎn)化成一個“解析器”,而這個解析器便是ParsedRoute類。在需要拆分一個URL字符串(如"Home/Index/5")的時候,便會調(diào)用ParsedRoute類的Match方法,由此得到一個RouteValueDictionary對象,其中包含了Pattern中定義的名稱,和一些值的映射關(guān)系。

可能您也能夠輕易實現(xiàn)這樣的功能,不過既然微軟已經(jīng)幫我們做好了,我們也不妨直接使用一下,偶爾用來拆拆字符串也是挺方便的。只可惜RouteParser和ParsedRoute都是由internal修飾的,我們無法直接訪問到。那么就用點小技巧吧……說實話,其實您會發(fā)現(xiàn)也就這么一回事,“反射”罷了。因此,我們便學(xué)著ASP.NET Routing的做法,構(gòu)建兩個類吧:

解析URL的兩個類

 
 
 
  1. internal static class RouteParser
  2. {
  3.     public static ParsedRoute Parse(string routeUrl) { ... }
  4. }
  5. internal class ParsedRoute
  6. {
  7.     public RouteValueDictionary Match(string virtualPath, RouteValueDictionary defaultValues) { ... }
  8. }

我們目前的做法算是一種Hack,為了保證其可維護(hù)性,我會選擇與目標(biāo)類庫/框架的接口盡可能完全一致的做法。這么做的好處在于,我可以很輕易地理解正在實現(xiàn)的功能,一旦出現(xiàn)了任何問題,就可以直接去找對應(yīng)的內(nèi)部實現(xiàn),而不用在一堆堆的反射關(guān)系中“翱翔”。

接著便可以實現(xiàn)我們需要的效果了。在這里,我使用了FastReflectionLib來加快反射調(diào)用的性能。雖然我不是一個追求性能極致的Geek,但是如果有一種幾乎不耗費額外代價,就能得到數(shù)百倍的性能提升,何樂而不為呢?

 
 
 
  1. internal static class RouteParser
  2. {
  3.     private static MethodInvoker s_parseInvoker;
  4.     static RouteParser()
  5.     {
  6.         var parserType = typeof(Route).Assembly.GetType("System.Web.Routing.RouteParser");
  7.         var parseMethod = parserType.GetMethod("Parse", BindingFlags.Static | BindingFlags.Public);
  8.         s_parseInvoker = new MethodInvoker(parseMethod);
  9.     }
  10.     public static ParsedRoute Parse(string routeUrl)
  11.     { 
  12.         return new ParsedRoute(s_parseInvoker.Invoke(null, routeUrl));
  13.     }
  14. }
  15. internal class ParsedRoute
  16. {
  17.     private static MethodInvoker s_matchInvoker;
  18.     static ParsedRoute()
  19.     {
  20.         var routeType = typeof(Route).Assembly.GetType("System.Web.Routing.ParsedRoute");
  21.         var matchMethod = routeType.GetMethod("Match", BindingFlags.Instance | BindingFlags.Public);
  22.         s_matchInvoker = new MethodInvoker(matchMethod);
  23.     }
  24.     private object m_instance;
  25.     public ParsedRoute(object instance)
  26.     {
  27.         this.m_instance = instance;
  28.     }
  29.     public RouteValueDictionary Match(string virtualPath, RouteValueDictionary defaultValues)
  30.     {
  31.         return (RouteValueDictionary)s_matchInvoker.Invoke(this.m_instance, virtualPath, defaultValues);
  32.     }
  33. }

兩個類其實都是使用反射,從類庫中獲取合適的MethodInfo,然后交給MethodInvoker去執(zhí)行。其他的……由于代碼過于簡單,我都不知道還需要解釋什么東西。最后就使用xUnit測試一下吧:

解析URL效果測試

 
 
 
  1. public class ParseRouteTest
  2. {
  3.     [Fact]
  4.     public void Basic_Parsing()
  5.     {
  6.         var parsedRoute = RouteParser.Parse("{controller}/{action}/{id}");
  7.         var values = parsedRoute.Match("Home/Index/5", null);
  8.         Assert.Equal("Home", values["controller"]);
  9.         Assert.Equal("Index", values["action"]);
  10.         Assert.Equal("5", values["id"]);
  11.     }
  12. }

說實話,這個方法并沒有太多技術(shù)含量,由于我們將自己的實現(xiàn)和目標(biāo)實現(xiàn)完全對應(yīng)起來,所以我們所要做的,似乎也都是些機械的“映射”功能而已。這就引發(fā)了我的一個想法,既然很“機械”,那么為什么不去讓它“自動”完成呢?例如,我們完全可以寫一個類庫,來實現(xiàn)這樣的效果:

 
 
 
  1. [Type("System.Web.Routing.ParsedRoute, ...")]
  2. interface IParsedRoute
  3. {
  4.     RouteValueDictionary Match(string virtualPath, RouteValueDictionary defaultValues);
  5. }
  6. [Type("System.Web.Routing.RouteParser, ...")]
  7. interface IRouteParser
  8. {
  9.     [Static]
  10.     IParsedRoute Parse(string url);
  11. }

通過定義接口和標(biāo)記,我們可以直接“聲明”需要“挖掘”出來的類型是什么。然后自然可以有框架為我們進(jìn)行匹配:

 
 
 
  1. IRouteParser parser = HackFactory.Create();
  2. IParsedRoute route = parser.Parse("{controller}/{action}/{id}");
  3. RouteValueDictionary values = route.Match("Home/Index/5", null);

是不是一下子變得爽快了許多?簡單想了想,這樣的框架從技術(shù)上來說似乎并沒有太多困難。

以上就對ASP.NET Routing中的“解析URL”功能進(jìn)行了介紹。本文來自老趙點滴:《復(fù)用類庫內(nèi)部已有功能》


網(wǎng)站標(biāo)題:ASP.NETRouting之“解析URL”功能詳解
新聞來源:http://www.dlmjj.cn/article/djedicj.html