1. 程式人生 > >ASP.NET沒有魔法——ASP.NET MVC路由

ASP.NET沒有魔法——ASP.NET MVC路由

文件相對路徑 register 以及 out insert 技術分享 順序 reg 沒有

  之前的文章中介紹了My Blog文章維護功能的開發,開發過程中使用Area的方法建立了用於維護文章的Controller、View和Model。但是無論代碼怎麽變對於瀏覽器來說都是通過一個url地址去訪問,現在My Blog可用的url有以下幾個:
  http://localhost:52356/ -- 主頁
  http://localhost:52356/Home --主頁
  http://localhost:52356/Post --博客列表
  http://localhost:52356/Post/Get/1 --ID為1的博客內容
  http://localhost:52356/Home/About --網站關於信息

  http://localhost:52356/Admin/Home --管理首頁
  http://localhost:52356/Admin/PostManagement --管理博客列表
  http://localhost:52356/Admin/PostManagement/Update/1 --更新ID為1的博客內容
  http://localhost:52356/Admin/PostManagement/Insert --添加文章

  從上面列表可以發現可以通過兩個地址訪問主頁,但是管理主頁只有一個地址,可以像主頁一樣把Home省略掉嗎?出錯了?為什麽?而且為什麽文章添加、修改都需要Action名稱,但是列表頁的Index不需要?

  技術分享

  根據URL來決定執行哪一個控制器的活動是ASP.NET MVC的路由機制決定的,本文將從以下幾點來介紹ASP.NET的路由機制:

  ●Web服務器靜態資源的訪問
  ●ASP.NET中的路由機制
  ●路由表
  ●路由的註冊
  ●路由註冊參數說明
  ●關於Area的路由

Web服務器靜態資源的訪問

  當訪問一個HTTP服務器上的靜態文件時,一般通過域名+文件相對路徑來訪問,如最開始的使用html編寫的文章列表頁面:

  技術分享

ASP.NET中的路由機制

  在ASP.NET 提供了路由(Routing)機制,它分析url來決定將請求轉到適當的位置,不再需要指定物理位置,但是ASP.NET的三種Web框架中路由機制也主要應用於MVC框架,其余的Web Form和Web Page常用的仍舊是通過物理地址訪問(註:ASP.NET中的三種Web框架均可使用路由)。

路由表

  ASP.NET中可以使用路由的原因是一個ASP.NET應用中有一個路由表(RouteTable),在My Blog項目中的App_Start目錄下的RouteConfig.cs文件中的註冊路由(RegisterRoutes)方法的參數就是路由表,是一個System.Web.Routing.RouteCollection類型,以下是該類型的定義:

  技術分享

  技術分享

  註:在路由表的定義中有一個MapPageRoute的方法,該方法用於給Web Forms應用註冊路由,並且從參數可以看出通過指定一個routeUrl去匹配一個物理文件路徑。

  那MVC的路由註冊方法在什麽地方?MVC的路由僅僅是路由表的一個拓展,它位於System.Web.Mvc命名空間下:

  技術分享

 

路由的註冊

  再回到RouteConfig類中註冊路由的方法,這個方法它有這樣幾個作用:

  技術分享 

  1. 添加一個名稱為Default的路由條目。
  2. 路由用來匹配{controller}/{action}/{id}這種模式的url。
  3. controller和action的默認值是Home和Index,id是可選的(這裏就解釋了為什麽http://localhost:52356/ 能夠訪問到HomeController的Index Action),而且在訪問列表頁面的Index Action的時候也不需要提供,因為默認已經被設置為Index。
  4. namespaces指定了只匹配命名空間在My_Blog.Controllers下的Controller(它解決了Home Controller重名的問題)。

路由註冊參數說明

  1. name:

  路由信息的唯一標識,當註冊兩條name一致的路由會拋異常。
  2. url:

  它是一個url模板,它的格式與url一樣,通過/分隔成多個段落,每一個段落可以由文字和變量占位符構成,其中變量占位符使用花括號{}擴住變量名稱,文字不能有特殊字符。在一個段落中可以定義多個變量,但是變量之間一定要用文字隔開,如/{controller}-{action}/是不正確的。在mvc中必要的變量有{controller}和{action},那麽{id}呢?每次創建默認MVC項目的路由註冊模板中都有id這個變量它不是必要的嗎?
  做個實驗,把url模板中的{action}變量刪除:

  技術分享

  運行程序後程序能夠運行,但是出現以下兩個問題:
  1). 使用Html.ActionLink創建的鏈接action參數失效,只生成一個空連接:

  技術分享

  技術分享

  2). 除了index action的連接都無法打開了:
  http://localhost:52356/Home/About 會被識別為http://localhost:52356/Home/ 然後加上默認的index跳轉到主頁。
  而Post沒有被設置默認參數直接無法找到:

  技術分享

  3). 當把默認action默認參數也刪除時,啟動應用程序就直接拋異常了:

  技術分享

  技術分享

  註:但是刪除{id}或者改變它的名稱都不會錯處,僅僅會影響action的參數綁定。

  3. defaults:

  路由的默認值,註意它不僅僅是路由模板的變量默認值,路由模板只是包含在路由值這個集合中,這也就是上面實驗中把url目標的action變量刪除後,它的默認值仍然有效的原有,關於路由值後面再詳細介紹。

  4. namespaces:
  一個命名空間數組,代表這個路由只匹配這些命名空間下的controller。避免多個模塊中存在同名Controller。所以如果一個應用程序存在多個模塊,那麽最好的方式就是針對每一個模塊的路由都加上自己模塊Controller的命名空間避免沖突。

  5. constraints:
  MapRoute方法中還有一個constraints參數,該參數是一個正則表達式集合,它用來驗證url中的參數是否符合表達式的要求。

關於Area的路由

  Area是MVC用來分隔功能的,通過VS來對一個MVC應用添加Area之後,會自動添加一個{Area名稱}AreaRegistration.cs的文件,該文件包含了對這個Area的路由註冊,它的url模板根據area的名稱進行了硬編碼:

  技術分享

  該路由只匹配由Admin開頭的url。
  如果存在重名可能,那麽最好添加該Area的Controller的命名空間。

如何在ASP.NET MVC中使用路由 

  上面介紹了註冊路由的方法和它的參數,並且根據示例代碼可以看出,在MVC中註冊路由只需要提供url模板和變量的默認值即可,如果應用中可能會存在同名Controller那麽只需要再加入命名空間就好,這裏就簡單總結一下:
  ● ASP.NET MVC路由的url模板必須設置{controller}和{action}變量。
  ● 路由中可以通過defaults參數對路由值(包括模板變量)設置默認值。
  ● 如果存在命名沖突可以通過namespaces數組解決。
  ● 如果使用area來分隔功能,那麽註意其自動生成的url模板,如果可能存在命名沖突,可以使用namespaces屬性解決。
  ● 路由表是有序的,當匹配到一個路由後,後續的路由將不會被匹配,所以要註意順序,以免被路由到錯誤的處理器(註:關於處理器後續文章介紹)。

小結

  本章簡單介紹了ASP.NET的路由機制,以及在MVC程序中用於註冊路由的方法和參數,並總結了路由的一些使用方法,在後續文章中將對路由的工作機制進一步介紹。

參考:

  https://msdn.microsoft.com/en-us/library/cc668201.aspx#setting_default_values_for_url_parameters

本文連接:http://www.cnblogs.com/selimsong/p/7660176.html

ASP.NET沒有魔法——目錄

ASP.NET沒有魔法——ASP.NET MVC路由