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

來源:互聯網
上載者:User

前面我們已經提到過,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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.