標籤

2011年11月8日 星期二

MVC Routing 觀念與技巧

參考The will will Web
http://blog.miniasp.com/post/2011/08/01/ASPNET-MVC-Developer-Note-Part-21-Routing-Concepts-and-Skills.aspx


以下文字用來描述上圖標號的部分:
  1. ASP.NET 執行的起點就在於 HttpApplication 的 Application_Start() 方法,所有 Routing 都會定義在此,其中 RouteTable.Routes 是一個公開靜態物件,用來儲存所有的 Routing 規則,其物件型別為 RouteCollection
  2. 在預設 RegisterRoutes 方法中的 IgnoreRoute 用來定義 不要透過 Routing 處理的網址
    註: IgnoreRoute 擴充方法是 ASP.NET MVC (System.Web.Mvc) 的一部份。
  3. {resource} 代表一個 路由變數(RouteValue),其名稱為 resource,但在這裡其實取任何名字都可以,這裡只代表一個變數空間 (PlaceHolder) 罷了。總之就是代表一個「位置」,可以放入一個用不到的變數。
  4. {*pathInfo} 也是代表一個 RouteValue 名稱為 pathInfo,但名稱前面的星號 ( * ) 代表 CatchAll 的意思,這個名為 pathInfo 的 RouteValue 會是完整的 PATH INFO 扣除 標號 3 比對到的網址。例如:若網址是 /TEST.axd/a/b/c/d 則 pathInfo 所得到的值為 a/b/c/d,如果沒加上星號 ( * ) 該 pathInfo 就會等於 a 而已。而在這裡其實取任何名字都可以,這裡也只是代表一個變數的位置。
  5. MapRoute 則是最常用來定義 Routing 規則的擴充方法。
    註: MapRoute 擴充方法是 ASP.NET MVC (System.Web.Mvc) 的一部份。
  6. 定義 Route 名稱,這個名稱雖然少用,但是開發到較為進階的 Routing 技巧時會用到。
  7. 定義 網址格式 與每個 網址段落(Path Segment) 的 RouteValue 參數名稱
    注意: 該網址不能以斜線 ( / ) 開頭。
  8. 定義各 RouteValue 參數預設值
路由開發技巧
技巧 1:替 Routing 網址設立條件限制
由於 ASP.NET MVC 有個很重要的特性:以習慣取代設定 (Convention over Configuration),所以當我們從網址路徑對應到 Controller 的過程中,網址列上的路由變數會自動對應到 Action 方法的參數中,例如我們在 Global.asax.cs 檔案中有以下路由定義:
routes.MapRoute(
    "Product",
    "Product/{productId}",
    new {controller="Product", action="Details"}
);
而我們的 Action 方法的內容如下:
public ActionResult Details(int productId)
{
    return View();
}
因為我們 Action 方法裡的參數是 int 型別,所以傳入的 productId 路由變數必須要是「整數」,如果不是整數的話,就會導致 The parameters dictionary contains a null entry for parameter 'productId' of non-nullable type 'System.Int32' for method 'System.Web.ActionResult Details(Int32)' in ... 的錯誤發生。

要避免這種無效的網址路由比對,我們可以在定義路由時多下一些限制條件,來進一步比對 網址段落(PathSegment) 是否符合 路由變數(RouteValue) 的格式要求,我們以上述例子來進一步修改路由定義,如下程式範例,我們多增加了一個參數傳入 MapRoute 參數,其中 \d+ 是 正規表示式(RegEx) 樣式:
routes.MapRoute(
    "Product",
    "Product/{productId}",
    new {controller="Product", action="Details"},
    new {productId = @"\d+" }
 );
注意:這裡的 RegEx 樣式在比對時會自動幫你加上 ^ 開頭與 $ 結尾,也代表這個樣式一定會比對完整的網址段落(Path Segment)。
如此一來,當網址輸入的格式是 /Product/CellPhone 的時候,就不會比對到 "Product" 這一條路由規則。


技巧 3:讓 ASP.NET MVC 與 ASP.NET Web Form 和平共處
基於 ASP.NET MVC 與 ASP.NET Web Form 的運作方式不同,所以通常這兩種架構下的程式在預設的情況下都能正常的運作,只有在某些特殊的設定下才會兩邊互相干擾,當你網站部署時遇到互相干擾的狀況時,就可以套用以下 Routing 技巧,設定特定一些路徑不要走 ASP.NET MVC 的執行管線。
以下是一些過濾掉路由規則定義的程式碼範例:
  • 忽略所有 *.aspx 的網址路徑
    routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
  • 忽略所有在 Page 目錄下的所有程式與檔案 ( 請注意,這是忽略 Routing 而已,改由 IIS 來判斷要用何種 Handler 來處理這次 HTTP 要求 )
    routes.IgnoreRoute("Page/{*pathInfo}");
  • 忽略所有在 Page 目錄下的所有檔案 ( 另一種寫法 )
    routes.Add(new Route("Page/{*pathInfo}", new StopRoutingHandler()));
另外還有一點也值得注意,也就是 Routing 的動作其實是在執行 HttpHandler 執行之前,他是一個專門用來分配 Request 的模組,所以可以透過 Routing 的定義與設定來決定到底後續要執行 ASP.NET MVC 還是 ASP.NET Web Form,在 IIS7 的 HTTP Request 的執行順序中,UrlRoutingModule (Routing module) 的執行順位如下圖示,執行事件名稱為 Resolve Cache 這一步之後(PostResolveRequestCache):

再整理,待續....



沒有留言:

使用 DiskSpd 測試磁碟效能

  DiskSpd 是微軟創建的命令行磁碟測試工具。它結合了強大的IO工作負載定義來測量磁碟效能。由於它支援自由配置和調整參數,使其成為存儲效能測試、驗證和基準測試的理想工具。 步驟 1. 從 GitHub (說明) https://github.com/Microsoft/di...