Asp.net 路由詳解
網路上關於asp.net路由知識的一些資源:
https://www.cnblogs.com/cklovefan/p/7785307.html
https://blog.csdn.net/slowlifes/article/details/72461440
一、請求一個ASP.NET mvc的網站和以前的web form是有區別的,ASP.NET MVC框架內部給我們提供了路由機制,當IIS接受到一個請求時,當 未設定RouteTable.Routes.RouteExistingFiles 屬性時,asp.net 會先看是否請求了一個靜態資源(.html,css,js,圖片等),如果不是則說明是請求的是一個動態頁面,就會走asp.net的管道,mvc的程式請求都會走路由系統,會對映到一個Controller對應的Action方法。下面通過一個ASP.NET MVC5專案來詳細介紹一下APS.NET MVC5路由系統的機制。
asp.net 程式啟動時,會執行global.asax檔案中的Application_Start方法,實現區域、路由、過濾器等全域性物件註冊;
protected void Application_Start() { //===============註冊區域=============== AreaRegistration.RegisterAllAreas(); //===========註冊過濾器====================== FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); //===========註冊路由====================== RouteConfig.RegisterRoutes(RouteTable.Routes); //==============註冊css、js檔案繫結================== BundleConfig.RegisterBundles(BundleTable.Bundles); }
路由註冊
public static void RegisterRoutes(RouteCollection routes) { //===============靜態路徑訪問也需要提交到路由處理程式======================= RouteTable.Routes.RouteExistingFiles = true; //===============不需要傳遞到asp.net管道的Url================= routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.IgnoreRoute("Content/{*catchall}"); routes.IgnoreRoute("Scripts/{*catchall}"); //=================需要把自定義的靜態路由放到預設路由前面才能確保路由解析準確,為啥子?bug?=== Route testRoute= routes.MapRoute("MyRoute", "grids/list", new { controller = "Grid", action = "ListGrid" }); //routes.Add() //===========定義預設的路由處理程式======================= routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); }
上述路由定義了兩類路由處理:
當url為: grids/list時,將路由傳遞給命名為Grid 的控制器的ListGrid方法;
其它的url通過預設的路由對映程式處理,不過比較奇怪的是需要將靜態路由處理程式定義在預設路由之前,否則不能正常的處理訪問URL,現在還不清楚是什麼原因,why????
註冊的預設路由是三段式的:
Url段的數量 |
例項 |
Route對映 |
0 |
mydomain.com |
controller = Home action = Index |
1 |
mydomain.com/Home |
controller = Home action = Index |
2 |
mydomain.com/Home/Index |
controller = Home action = Index |
3 |
mydomain.com/Home/Index/All |
ID=All |
當需要訪問更多分段時,註冊類似路由:
routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
匹配的路由如下:
Url段的數量 |
例項 |
Route對映 |
0 |
mydomain.com |
controller = Home action = Index |
1 |
mydomain.com/Customer |
controller = Customer action = Index |
2 |
mydomain.com/Customer/List |
controller = Customer action = List |
3 |
mydomain.com/Customer/List/All/Delete/Perm |
controller = Customer action = List id = All catchall = Delete /Perm |
同一區域、不同名稱空間的控制器最好不要重名,如果發生算了重名的情況,通過指定名稱空間優先順序,設定處理控制器,如:
存在以下不同名稱空間的同名控制器:
WebApplication1.Controllers.HomeController
WebApplication1.Controllers1.HomeControlle
如下設定路由:
public static void RegisterRoutes(RouteCollection routes) {
routes.MapRoute("Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new string[] { "WebApplication1.Controllers" }
);
}
在某些情況下,我們需要將路由限制到特定值,可如下實現:
public static void RegisterRoutes(RouteCollection routes) {
routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { controller = "^H.*", action = "^Index$|^About$", httpMethod = new HttpMethodConstraint("GET")},
new[] { "URLsAndRoutes.Controllers"});
}
設定路由只能是H字母開頭,方法只能是Index和About,訪問方式只能是Get