MVC 3 中的路由以及區域詳解


     我們都知道MVC 3 程序的所有請求都是先經過路由解析然后分配到特定的Controller 以及 Action 中的,為什么這些知識講完了Controller Action Model 后再講呢?這個東西我個人感覺比較的抽象吧!如如您有基礎,看起來一點也不費力,如果您沒有基礎的話,您連Controller  Action 都不知道是什么,那您怎么理解路由呢?嘿嘿僅僅是個人的看法!如果您還沒有了解MVC 3 的一些基本的信息請您按照我下面的導航來,先了解MVC 3 的其他知識,然后再看下這篇文章。前面文章但凡涉及路由知識的東東都有對路由的簡單的解釋,對於不還不了解路由概念的人來說閱讀下面這幾篇文章沒什么障礙。

好下面咱就好好的說說路由Routing
第一 如果Routing 的命名空間是System.Web.Routing 在這說一下Routing不是MVC 3 獨有的,在webForm中也可是使用。當然我沒有使用過,不過大家做過項目的都使用過url重寫吧!如果您還沒有用到過url重寫技術的話,證明您做的項目不需要 SEO 。

第二 Routing的作用:
  1. 確定Controller  2. 確定Action 3. 確定其他參數(一般就是Action方法的參數了) 4. 根據識別出來的Controller Action 將請求傳遞給對於的Controller 和 Action 。

第三 Routing 是怎么工作的:
      我們思考一個問題對於下面的這個url   http://www.cnblogs/wlitsoft/blogs/123 為什么當我訪問這個url的時候是怎么實現Controller 就是 wlitsoft Action 就是 blogs 參數就是123的呢?
好我們都知道MVC 3 項目的跟目錄下有個全局文件(global.asax)當然webform 中也用這個文件,下面我們看看它和webform的有什么不同或者說它新加了什么方法。

1 Routes.MapRoute(
2                 "Default", // 路由名稱
3                 "{controller}/{action}/{id}", // 帶有參數的URL
4                 new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 參數默認值
5             );

我們會發現上面這幾行代碼。這幾行代碼就定義了一個路由匹配規則,下面我們將一下具體的參數是什么意思。
   - name 參數:規則名稱,不可以重復,即路由名必須是唯一的。

  - url 參數: 將要識別的參數括起來即可, 比如: {controller}/{action}/{id} 這里的{}就是占位符 您可以這樣理解大家都用過string類的Format方法吧!
        例如:string.Format("{0}aaaa{1}bbb",“1”,“2”);  怎么樣明白了吧!

  - defaults 參數:url參數的默認值,當我們新建了一個mvc 項目的時候當運行瀏覽可以看到地址欄沒有任何的參數只有一個比如http://localhost:32112/ 它什么就轉向了home下的index頁面呢?這就是這個參數的作用了,它可以定義默認的controller action 以及 id參數 這個還得說一下您看上面的代碼為什么id不給一個具體的值而是給一個UrlParameter.Optional 呢 這個呢 因為您不能保證id的類型是int 的還是 stirng 等等 ,寫id= UrlParameter.Optional 它會根據id的類型還具體的指定什么類型的默認值比如int型的就是0吧!

  - constraints參數: 這個參數在再上面的代碼中沒有出現 我先提前說下 然后一會兒咱再看代碼吧!
                                 這個參數的作用是用來限定每個參數的規則或http請求的類型constraints屬性是一個RouteValueDictionary對象,也就是一個字典表, 但是這個字典表的值可以有兩種:1.用於定義正則表達式的字符串。正則表達式不區分大小寫  2.
一個用於實現 IRouteConstraint 接口且包含 match 方法的對象。
例如:通過正則表達式可以規定參數格式,比如controller 參數只能是4位數字。

new { controller = @"\d{4}"}

通過第IRouteConstraint 接口目前可以限制請求的類型。
例如:比如限制一條路由規則只能處理GET請求:

httpMethod = new HttpMethodConstraint( "GET", "POST" )

第四 怎么優化url
    對於一個網站來說為了SEO友好,一個url層數不要超過3層:但是按照我們默認的匹配規則{controller}/{action}/{id} 它是3層以及不符合SEO了怎么辦呢?稍微修改下就ok了看怎么修改{controller}/{action}-{id}  我們都知道C#的命名規則是字母數字下划線不能以字母開頭,所以{action}-{id} 映射出來的url 不會被匹配成一個變量。

第五 路由匹配是有優先級的
    路由匹配是有優先級的也就是說您定義路由規則的的時候是有順序的,假如您定義了一個非常復雜的路由但是您放在了最下面,恰巧呢上面的路由規則有符合的那您就掛了,永遠不會匹配到您定義的那個路由。怎么辦捏 把不容易匹配的路由放在最上面,把最容易匹配的路由放在最下面,這里我還得說一點 有個路由能匹配所有的url什么呢 看下面代碼
{*AllUrl}

第六 區域 area  比如 一個管理系統 都有后台功能吧!但是我們想讓后台管理這塊和網站前台分開或這說后台管理這快存再一個單獨的web.config 配置文件怎么辦呢?這里區域的概念出來了我們首先新建一個區域。

完事后會看到一個AreaAdminAreaRegistration.cs 文件 打開它

1 public override void RegisterArea(AreaRegistrationContext context)
2         {
3             context.MapRoute(
4                 "AreaAdmin_default",
5                 "AreaAdmin/{controller}/{action}/{id}",
6                 new { action = "Index", id = UrlParameter.Optional }
7             );
8         }

重寫了一個方法 那 全局文件中怎么識別呢 ? 看下全局文件

1  protected void Application_Start()
2         {
3             AreaRegistration.RegisterAllAreas();
4 
5             RegisterRoutes(RouteTable.Routes);
6         }

第3行是不是定義了  所以 區域這個路由規則除了前面加了一個AreaAdmin 區域名 和其他的沒有任何的區別了吧!下面我們新建一個Controller 比如AdminHome 我們先避免和以前的Controller重名一會兒再說為什么。看下運行結果

很正常吧!但是如果我要新建一個HomeController 呢 就是 建一個 以前前台有過的Controller  ,運行一下

也沒問題是吧!好下面咱再訪問一下另一個homecontroller 就是 前台的那個,看下出什么異常

 

 出問題了是吧!因為程序中存在兩個HomeController 它不知道要訪問哪個!,所以根據錯誤提示我們還得再原有的路由中加點東西 加個namespace。區分一下兩個HomeController

new string[] { "_2012_6_16Mvc2Test.Controllers" }

ok 搞定。

第七 路由測試
  我們不能保證自己寫的路由規則一定能被匹配到 好下面介紹一個工具專為分析路由匹配的叫什么呢 叫RouteDebug
首先引入dll  然后再在全局文件中的Application_Start() 方法里加入如下代碼

RegisterRoutes(RouteTable.Routes);
RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);

一切搞定 運行一下吧!


 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM