RouteData解析過程
在ASP.NET MVC中,服務器收到來自客戶端的請求后,會經過一些列的處理拿到請求的數據,比如在Pipeline 管線事件中,通過訂閱適當的事件,將HttpContext
作為參數傳入HttpContextWrapper
進行封裝,然后取得當前路由集合的數據RouteData
進行解析,拿到具體的參數,包括請求路徑、請求的參數、IRouteHandler
等,通過IRouteHandler
的GetHttpHandler
返回一個IHttpHandler
對象,通過該對象的ProcessRequest
對請求進行處理,然后控制器工廠通過RouteData
中匹配的Controller進行反射構造一個Controller
,Controller
調用IController
的Excute
方法,同樣是通過反射拿到當前請求的Action
,最后執行Action
,返回客戶端數據,完成本次的請求。整體流程圖如下所示:
在這個過程中,RouteData
中的路由 起到了很大的作用。Routing的作用:首先通過HTTP請求,並解析Url請求中Controller
和Action
以及附加數據,其次將識別出來的數據傳遞給Controller
的Action
(Controller的方法)。這是Routing組件的兩個重要的作用!
路由規則實例解析
實例一:系統默認提供的路由格式
下面是系統給的默認代碼:
1 public static void RegisterRoutes(RouteCollection routes) 2 { 3 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 4 5 routes.MapRoute( 6 "Default", // 路由名稱 7 "{controller}/{action}/{id}", // 帶有參數的 URL 8 new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 參數默認值 9 ); 10 }
Url格式為:http://localhost:80/home/index 對應規則為:{controller}/{action}/{id} 黑體部分就是對應部分。這還是有默認值的情況。
詳細匹配應該為:http://localhost:80/Custom/Detials/1 。去掉主機域名,剩下的對應就是匹配Controller和Action了。通過Routing組件解析這個Url,Controller是Custom,Action是Detials。傳遞過去的Id是1。這就是使用了MapRoute( string name, string url, object defaults)
;這個方法的重載。
實例二:不使用默認值的Url路由規則
函數簽名:MapRoute( string name, string url);
routes.MapRoute("沒有默認值路由規則", "{controller}/{id}-{action}");
適合的Url例子:http://localhost:80/Custom/1-Detials
它將不匹配http://localhost:80/
實例三:帶名稱空間的Url路由規則
函數簽名:MapRoute( string name, string url, string[] namespaces);//路由名,Url規則,名稱空間
1 routes.MapRoute( 2 "MyUrl", // 路由名稱 3 "{controller}/{id}-{action}", // 帶有參數的 URL 4 new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // 參數默認值 5 new string[] { "MvcDemo.Controllers" }//命名空間 6 );
Url:http://localhost:0000/Custom/1-Detials
這個例子是帶命名空間的路由規則,這在Aeras使用時非常有用。
實例四:帶約束的路由規則
函數簽名:MapRoute( string name, string url, object defaults, object constraints);//路由名,Url規則,默認值,名稱空間
1 routes.MapRoute( 2 "Rule1", 3 "{controller}/{action}-{Year}-{Month}-{Day}}", 4 new { controller = "Home", action = "Index", Year = "2010", Month = "04", Day = "21" }, 5 new { Year = @"^\d{4}", Month = @"\d{2}" } 6 );
實例五:帶名稱空間,帶約束,帶默認值的路由規則
函數簽名:MapRoute( string name, string url, object defaults, object constraints, string[] namespaces);
1 routes.MapRoute( 2 "Rule1", 3 "Admin/{controller}/{action}-{Year}-{Month}-{Day}", 4 new { controller = "Home", action = "Index", Year = "2010", Month = "04", Day = "21" }, 5 new { Year = @"^\d{4}", Month = @"\d{2}" }, 6 new string[] { "MvcDemo.Controllers" } 7 );
Url:http://localhost:14039/Admin/home/index-2010-01-21
實例六:捕獲所有的路由
1 routes.MapRoute( 2 "All", // 路由名稱 3 "{*Vauler}", // 帶有參數的 URL 4 new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 參數默認值 5 );
1 routes.IgnoreRoute("{resource}.axd/{*pathInfo}");//是忽略這個規則的Url
1 AreaRegistration.RegisterAllAreas();//注冊所有的Areas 2 RegisterRoutes(RouteTable.Routes);//注冊自定義規則 3 4 ////調試用語句,需要下載RouteDebug.dll,並添加引用!加入這句話后就可以測試Url路由了。 5 //RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);