程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> ASP.NET的路由系統:根據路由規則生成URL

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

編輯:關於ASP.NET

前面我們已經提到過,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模板中定義的變量的值都能被提供,而這些變量值具有三種來源,分別是路由對象定義的默認變量值、指定RequestContext的RouteData提供的變量值(Values屬性)和手工提供的變量值(通過values參數指定的RouteValueDictionary對象),這三種變量值的選擇優先級由低到高。同樣以之前定義關於獲取天氣信息的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。這充分證實了上面提到的關於變量選擇優先級的結論。

本文配套源碼: http://www.bianceng.net/dotnet/201211/593.htm

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved