閱讀39 返回首頁    go 技術社區[雲棲]


ASP.NET的路由係統:根據路由規則生成URL

前麵我們已經提到過,ASP.NET 的路由係統主要具有兩個方麵的應用,其一就是通過注冊URL模板與物理文件路徑的匹配實現請求地址和物理地址的分離;另一個則是通過注冊的路由規測生成一個相應的URL。後者通過調用RouteCollection類型的GetVirtualPath方法來實現。[源代碼從這裏下載]

如下麵的代碼片斷所示,GetVirtualPath定義了兩個GetVirtualPath方法重載,它們共同的參數requestContext和values分別表示請求上下文(RouteData和HTTP上下文的封裝)和用於替換定義在URL模板中的變量站位符的值。另一個GetVirtualPath方法具有一個額外的字符串參數name,它表示集合中具體使用的路由對象的注冊名稱(調用MapPageRoute方法時指定的第一個參數)。而AppendTrailingSlash和LowercaseUrls決定在對生成的URL進行規範化的時候是否添加一個“/”字符(如果沒有),以及是否需要將URL轉化為小寫。

   1: public class RouteCollection : Collection<RouteBase>
   2: {    
   3:     //其他成員
   4:     public VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);
   5:     public VirtualPathData GetVirtualPath(RequestContext requestContext, string name, RouteValueDictionary values);
   6:          
   7:     public bool AppendTrailingSlash {  get;  set; }
   8:     public bool LowercaseUrls {  get;  set; } 
   9: }

如果調用GetVirtualPath方法時沒有指定具體采用的路由對象,會遍曆整個集合的每個路由對象並調用其GetVirtualPath方法,如果返回的VirtualPathData不會Null則直接將其作為返回值;否則(找不到匹配的路由對象)返回Null。如果在調用GetVirtualPath確定了具體使用的路由對象,則直接調用該路由對象的GetVirtualPath方法並返回其執行結果。

我們在調用GetVirtualPath方法的時候可以傳入Null作為第一個參數(requestContext),在這種情況下會基於當前HTTP上下文(對應於HttpContext的靜態屬性Current)創建一個RequestContext對象作為調用路由對象GetVirtualPath方法的同名參數,該參數包含一個空的RouteData對象。如果當前HTTP上下文不存在則直接拋出一個InvalidOperationException異常。

路由對象針對GetVirtualPath方法而進行的路由匹配隻要求URL模板中定義的變量的值都能被提供,而這些變量值具有三種來源,分別是、和,這三種變量值的選擇優先級。同樣以之前定義關於獲取天氣信息的URL模板為例,下麵是路由注冊代碼。

   1: public class Global : System.Web.HttpApplication
   2: {
   3:     protected void Application_Start(object sender, EventArgs e)
   4:     {
   5:         var defaults = new RouteValueDictionary { { "areacode", "010" }, { "days", 2 }};
   6:         var constaints = new RouteValueDictionary { { "areacode", @"0\d{2,3}" }, { "days", @"[1-3]{1}" } };
   7:         var dataTokens = new RouteValueDictionary { { "defaultCity", "BeiJing" }, { "defaultDays", 2 } };
   8:         RouteTable.Routes.MapPageRoute("default", "{areacode}/{days}", "~/weather.aspx", false, defaults, constaints, dataTokens);
   9:     }
  10: }

我們在Weather.aspx頁麵的後台代碼中通過如果如下的代碼調用RouteTable和Routes熟悉的GetVirtualPath方法生成三個具體的URL。

   1: public partial class Weather : Page
   2: {
   3:     protected void Page_Load(object sender, EventArgs e)
   4:     {
   5:         RouteData routeData = new RouteData();
   6:         routeData.Values.Add("areaCode","0512");
   7:         routeData.Values.Add("days","1");
   8:         RequestContext requestContext = new RequestContext();
   9:         requestContext.HttpContext = new HttpContextWrapper(HttpContext.Current);
  10:         requestContext.RouteData = routeData;
  11:  
  12:         RouteValueDictionary values = new RouteValueDictionary();
  13:         values.Add("areaCode", "028");
  14:         values.Add("days", "3");
  15:  
  16:         Response.Write(RouteTable.Routes.GetVirtualPath(null,null).VirtualPath + "<br/>");
  17:         Response.Write(RouteTable.Routes.GetVirtualPath(requestContext, null).VirtualPath + "<br/>");
  18:         Response.Write(RouteTable.Routes.GetVirtualPath(requestContext, values).VirtualPath + "<br/>");
  19:     }
  20: }

從上麵的代碼片斷我們可以看到:第一次調用GetVirtualPath方法傳輸的requestContext和values參數均為Null;第二次則指定了一個手工創建的RequestContext對象,其RouteData的Values屬性具有兩個變量(areaCode=0512;days=1),而values參數依然為Null;第三次我們同時為參數requestContext和values指定了具體的對象,而後者包含兩個參數(areaCode=028;days=3)。在瀏覽器上訪問Weather.aspx頁麵會得到如下圖所示的3個URL。這充分證實了上麵提到的關於變量選擇優先級的結論。

clip_image002

ASP.NET的路由係統:URL與物理文件的分離
ASP.NET的路由係統:路由映射
ASP.NET的路由係統:根據路由規則生成URL


作者:蔣金楠
微信公眾賬號:大內老A
微博:www.weibo.com/artech
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
原文鏈接

最後更新:2017-10-26 12:04:10

  上一篇:go  ASP.NET的路由係統:路由映射
  下一篇:go  ASP.NET MVC路由擴展:路由映射