天天看點

《Pro ASP.NET MVC 3 Framework》學習筆記之二十【URL和Routing】

自定義路由系統

通過前面的學習,我們能夠感受到路由系統的靈活性和可配置性,如果這些不能滿足我們的需求,我們可以自定義行為,下面會介紹如何自定義路由。

建立一個對RouteBase類的自定義實作

如果我們不喜歡标準Route對象比對URL的方式,或者想實作一些特别的東西。我們可以從RouteBase派生一個類來替代。派生出來的類可以讓我們自己控制URL的比對,參數的提取,以及Outgoing URL的建立。派生的類需要實作下面兩個方法:

1.GetRouteData(HttpContextBase httpContext):實作傳入的URL的比對機制。

   在每一個RouteTable.Routes進入的時候,MVC架構會輪流調用該方法直到其中的一次調用傳回非空值。

2.GetVirtualPath(RequestContext requestContext, RouteValueDictionary values):實作建立傳出的URL機制。

下面用一個例子來說明,假設現在我們要遷移一個程式到MVC,但是一些使用者已經存了程式連結書簽或者在腳本裡面寫死了。我們仍然需要支援原來的URL,我們能夠通過正常的路由系統來處理這種情況,這裡用這個例子來說明自定義路由。

建立一個LegacyController,代碼如下:

《Pro ASP.NET MVC 3 Framework》學習筆記之二十【URL和Routing】
《Pro ASP.NET MVC 3 Framework》學習筆記之二十【URL和Routing】

View Code

在這個簡單的Controller裡面,GetLegacyURL action方法會擷取一個參數并将這個參數傳遞給View。如果我們真的的要實作這個Controller,需要使用這個方法來檢索請求的檔案,但是這裡為了簡便,隻是在View裡面顯示請求的URL。注意:我們這裡對View裡面參數進行了Object的類型轉換。原因是View()方法本身有一個string參數的重載,如果這裡我們不轉換,View會把string參數當成某一個視圖的名字去尋找,顯然這裡我們不是要跳轉到某一個View,而是在預設的View上顯示出來就行。如圖所示:

《Pro ASP.NET MVC 3 Framework》學習筆記之二十【URL和Routing】

轉成object後,會認為是model而使用預設的View呈現。接着添加視圖GetLegacyURL.cshtml,代碼如下:

《Pro ASP.NET MVC 3 Framework》學習筆記之二十【URL和Routing】
《Pro ASP.NET MVC 3 Framework》學習筆記之二十【URL和Routing】

上面我們已經實作了從RouteBase派生,下面接着建立一個類LegacyRoute,如下所示:

《Pro ASP.NET MVC 3 Framework》學習筆記之二十【URL和Routing】
《Pro ASP.NET MVC 3 Framework》學習筆記之二十【URL和Routing】

該類的構造器需要傳入一個字元串數組作為參數,該參數呈現這個路由類支援的個别的URL。在GetRouteData方法裡面定義的部分就是路由系統調用來檢查是否能夠處理傳入的傳入的URL。如果不能處理請求,傳回null,并且路由系統會移動到到下一個路由重複該過程。如果能夠處理請求,就需要傳回包含了controller和action變量以及任何其他的想要傳遞給action方法的RouteData類的執行個體。

當我們建立RouteData對象時需要傳入要處理的值的handler,這裡我使用的是MvcRouteHandler類如:result=new RouteData(this,new MvcRouteHandler());

對絕大多數MVC應用程式,這個就是我們需要的類,因為它聯接着路由系統與一個MVC程式的controller/action model。當然,我們也可以實作一個替代MvcRouteHandler的類,也就是後面會介紹的建立自定義的Route Handler.

在上面的routing實作裡,我們将會路由任何傳給構造器的請求的URL。當擷取這樣一個URL時,我們添加controller和action的寫死值到RouteValues對象,我們也會傳遞請求的URL作為legacyURL屬性,注意這裡的屬性的名字必須和action方法的參數名比對,進而保證了我們建立的值能夠通過參數傳遞給action方法。最後一步就是注冊從RouteBase派生的新的路由。如:routes.Add(new LegacyRoute("~/article/Windows_3.1_Overview.html","~/old/.NET_1.0_Class_Library"));我們建立了一個LegacyRoute類的執行個體,并傳入了我們要路由的URL,然後使用Add方法添加到RouteCollection裡面。當我們請求傳入的URL時,就會被路由到我們定義的Controller,如下圖所示:

《Pro ASP.NET MVC 3 Framework》學習筆記之二十【URL和Routing】

建立Outgoing URL

為了支援建立Outgoing URL,我們需要實作GetVirtualPath方法。再一次說明,如果我們不能處理某個請求,我們通過傳回null值來讓路由系統知道,否則就傳回VirtualPathData類的執行個體。

代碼如下:

《Pro ASP.NET MVC 3 Framework》學習筆記之二十【URL和Routing】
《Pro ASP.NET MVC 3 Framework》學習筆記之二十【URL和Routing】

我們在傳遞segment變量或其他詳細的值時通常使用了匿名類型,但是在這裡,路由系統将這些轉換成了RouteValueDictionary對象。是以我們像這樣添加一個連結在View裡面,

如下所示:

《Pro ASP.NET MVC 3 Framework》學習筆記之二十【URL和Routing】
《Pro ASP.NET MVC 3 Framework》學習筆記之二十【URL和Routing】

建立的具有legacyURL屬性的匿名類型被轉換成了RouteValueDictionary對象,并且包含了一個同名的key。

在本例裡面,如果有一個key名為legacyURL并且它的值是我們傳入LegacyRoute類的構造器裡面的URL中的一個,我們決定能處理傳出的URL請求。

建立自定義路由處理程式(Route Handler)

前面我們提到過,在我們的路由裡面會依賴MvcRouteHandler類,因為它聯系着路由系統跟MVC架構。我們可以通過實作IRouteHandler接口來自定義Route Handle1r,如下所示:

《Pro ASP.NET MVC 3 Framework》學習筆記之二十【URL和Routing】
《Pro ASP.NET MVC 3 Framework》學習筆記之二十【URL和Routing】

IRouteHandler接口的目的就是提供一種方式來建立對IHttpHandler接口的實作,IHttpHandler接口是負責處理請求的,在這些接口的MVC實作中,controller會被找到,action方法會被調用,view會被呈現。結果會被寫到Response裡面。執行個體裡面的實作非常簡單,僅僅是寫了一個"Hello"到用戶端。

下面是注冊我們自己定義的路由:

routes.Add(new Route("SayHello", new CustomRouteHandler()));這時運作程式,輸入:http://localhost:57400/SayHello,頁面會顯示"Hello".

好了,今天的筆記做到這裡,後面的筆記是關于Areas和一些有關URL架構的最佳實踐。

晚安!

繼續閱讀