第二節:各類路由約束(動態路由、靜態路由、組合路由、正則約束、命名空間約束、區域內路由)

一. 什麼是路由html

   路由是約束URL的一組規範,那麼什麼是URL呢?通俗的來講URL是一個地址,經過該地址,用戶能夠訪問Web網站或者下載服務器上的文件。正則表達式

     好比下面就是兩組URL:服務器

    http://www.cnblogs.com/yaopengfei/p/7828441.html框架

    http://www.cnblogs.com/yaopengfei/p/7828441ide

  顯然咱們喜歡第二組,省略.html,會使該地址看起來更加簡潔,更加友好,利於SEO優化。測試

  那麼咱們怎麼實現這個簡單的需求呢?優化

  答案是:經過【路由】配置,因此如今咱們彷佛有點清晰了,路由能夠規定URL的特殊格式,使其達到特殊效果。網站

  在ASP.NET MVC框架中,經過路由配置URL,使用戶的URL請求能夠映射到Controller下的action方法中,執行相應操做,並接受URL中傳過來的參數,在MVC5框架中,在【RouteConfig.cs】類中進行路由規則的配置,以下圖:this

    

 

二. 從源碼的角度分析路由url

   咱們進入【RouteConfig】類中,發現核心代碼是調用【RouteCollection】類下的MapRoute方法,F12看源碼得知,MapRoute方法是RouteCollectionExtensions類的給【RouteCollection】類擴展方法的方法,而且有多個重載,以下圖:

  下面分析一下參數的含義:

    (1) name:  要映射的路由的名稱。

    (2) url:  路由的 URL 模式,能夠自定義路由的格式,能夠寫靜態路由,也能夠寫動態路由、組合路由等。

    (3) defaults:  一個包含默認路由值的對象,書寫路由的默認值。

    (4) constraints: 一組表達式,可使用正則指定 url 參數值的約束。

    (5) namespaces: 應用程序的一組命名空間,能夠縮小檢索路由對象匹配的範圍。

  底層源碼,有興趣能夠看一下:

 1  public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces)
 2         {
 3             if (routes == null)
 4             {
 5                 throw new ArgumentNullException("routes");
 6             }
 7             if (url == null)
 8             {
 9                 throw new ArgumentNullException("url");
10             }
11             Route route = new Route(url, new MvcRouteHandler()) {
12                 Defaults = CreateRouteValueDictionaryUncached(defaults),
13                 Constraints = CreateRouteValueDictionaryUncached(constraints),
14                 DataTokens = new RouteValueDictionary()
15             };
16             ConstraintValidation.Validate(route);
17             if ((namespaces != null) && (namespaces.Length > 0))
18             {
19                 route.DataTokens["Namespaces"] = namespaces;
20             }
21             routes.Add(name, route);
22             return route;

 

三. MVC中的幾類路由及其規則

1. 動態路由

1        routes.MapRoute(
2                 name: "Default",    //路由名稱
3                 url: "{controller}/{action}/{id}",   //路由規則
4                 defaults: new { controller = "First", action = "Index1", id = UrlParameter.Optional }  //默認值,當Controller或action爲空(省略)的時候調用
5             );

分析:路由規則爲 {controller}/{action}/{id} ,其中 {controller}、{action}、{id}爲三個參數,/ 爲格式分割符號,defaults中聲明的是默認路由,因此下面的測試結果:

http://localhost:7559/

http://localhost:7559/First

http://localhost:7559/First/index1

http://localhost:7559/First/Index1/2

都會跳轉到Index1的頁面。

  變種:將上面的代碼的URL分割符號稍微調整一下

1        routes.MapRoute(
2                name: "Default9",    //路由名稱
3                url: "{controller}/{action}-{id}",   //路由規則
4                defaults: new { controller = "First", action = "Index1", id = UrlParameter.Optional }  //默認值,當Controller或action爲空(省略)的時候調用
5            );

  請求地址就變成了:

http://localhost:7559/                                               【沒法訪問】

http://localhost:7559/First                                        【404找不到】

http://localhost:7559/First/index1                            【404找不到】

http://localhost:7559/First/Index1-1                         【能夠訪問】

 

2. 靜態路由

1         routes.MapRoute(
2                 name: "Default2",    //路由名稱
3                 url: "Ypf",   //路由規則,不區分大小寫,當輸入「ypf」時,會自動跳轉到下面的地址
4                 defaults: new { controller = "First", action = "Index1", id = UrlParameter.Optional }  //默認值,當Controller或action爲空的時候調用
5             );

靜態路由:url中是一個靜態值,訪問的URL只有輸入這個靜態值,才能訪問下面default中的默認值。

測試地址以下:

http://localhost:7559/                                            【沒法訪問】

http://localhost:7559/ypf                                      【 跳轉到index1頁面】

http://localhost:7559/First/index1                       【沒法訪問】

補充一下:MapRoute方法是能夠不須要寫參數名的,就像正常的調用方法同樣,因此上面的代碼能夠改寫:

1             routes.MapRoute(
2                 "Default3",    //路由名稱
3                 "Ypf",   //路由規則,不區分大小寫,當輸入「Ypf」時,會自動跳轉到下面的地址
4                  new { controller = "First", action = "Index1", id = UrlParameter.Optional }  //默認值,當Controller或action爲空的時候調用
5             );

 

3. 組合路由

1       routes.MapRoute(
2              "Default4",    //路由名稱
3              "Ypf/{action}",   //路由規則,不區分大小寫,規則相符的時候,會自動跳轉到下面的地址
4               new { controller = "First", action = "Index1" }
5          );

所謂的組合路由,就是靜態路由和動態路由相互組合使用,測試地址以下:

  http://localhost:7559/             【沒法訪問】       (分析:由於不知足路由規則,沒有輸入ypf)

  http://localhost:7559/ypf              【 跳轉到index1頁面】  

  http://localhost:7559/ypf/index1             【 跳轉到index1頁面】

  http://localhost:7559/Ypf/hh              【404找不到】        (知足路由規則,可是沒有hh這個action,因此404)

  http://localhost:7559/ypf/First/index1       【404找不到】        (知足路由規則,但這裏把First當作action,並無這個action,因此404)

 

4. 正則約束

1        routes.MapRoute(
2                "Default5",
3                 "{controller}/{action}_{Year}_{Month}_{Day}",
4                 new { controller = "First", action = "Index1", id = UrlParameter.Optional },
5                 new { Year = @"^\d{4}", Month = @"\d{2}", Day = @"\d{2}" }
6             );//正則路由

所謂的正則約束,是指能夠對URL中的參數使用正則表達式進行約束,上述代碼約束了Year必須是四位數字,Month和Day必須是兩位數字。

測試地址:

  http://localhost:7559/first/index1_2018_09_01         【跳轉到index1頁面】

  http://localhost:7559/first/index1         【沒法訪問】       (分析:由於不知足路由規則,沒有輸入{Year}_{Month}_{Day} 的參數)

  http://localhost:7559/first/            【沒法訪問】       (分析:由於不知足路由規則,沒有輸入{Year}_{Month}_{Day} 的參數

  http://localhost:7559/                【沒法訪問】        (分析:由於不知足路由規則,沒有輸入{Year}_{Month}_{Day} 的參數

 

5. 命名空間約束

1         routes.MapRoute(
2                  name: "Default6",
3                  url: "{controller}/{action}/{id}",
4                  defaults: new { controller = "Third", action = "Index", id = UrlParameter.Optional },
5                  namespaces: new string[] { "Ypf.MVC5" }
6             );

所謂的命名空間約束,即限定匹配範圍路由的檢索範圍,提升檢索速度。

特別注意:不能從外層控制器直接跳轉到內層Area內的控制器!!

測試地址:如下三個訪問地址,都會跳轉到index1頁面

  http://localhost:7559/

  http://localhost:7559/First

  http://localhost:7559/First/index1

 

6. Area區域內的路由

 1    public override void RegisterArea(AreaRegistrationContext context) 
 2         {
 3             //原路由
 4             //context.MapRoute(
 5             //    "TestOne_default",
 6             //    "TestOne/{controller}/{action}/{id}",
 7             //    new { action = "Index", id = UrlParameter.Optional }
 8             //);
 9 
10             //結合命名空間進行路由改造
11             context.MapRoute(
12                this.AreaName + "_default",
13                this.AreaName + "/{controller}/{action}/{id}",
14                new { area = this.AreaName, controller = "Sys_Admin", action = "Index", id = UrlParameter.Optional },
15                new string[] { "Ypf.MVC5.Areas." + this.AreaName + ".Controllers" }
16            );
17 
18         }

  指MVC5框架中Area區域單獨的一套路由規則,咱們能夠結合區域內的原路由,進行改造一番,如上述代碼。

 

相關文章
相關標籤/搜索