ASP.NET沒有魔法——ASP.NET MVC路由
之前的文章中介紹了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路由