1. 程式人生 > >Asp.net 路由詳解

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