Agenda
前言
現在開始進入Asp.net MVC原始碼世界,我們從路由開始切入一步一步進入MVC核心.
我有做一個可以針對於Asp.net MVC Debugger的專案,只要下中斷點就可輕易進入Asp.net MVC原始碼.
如下面動畫
介紹Route
每個HTTP請求MVC
使用路由的目標是Controller
和Action
,不像ASP.NET Web Form
處理物理文件(.aspx
文件),要執行Controller
和Action
名稱包含在HTTP請求中,ASP.NET MVC
需要通過解析HTTP請求得到正確的Controller
和Action
的名稱。
使用Route
比處理物理文件有以下幾個優勢:
- 靈活性:請求
URL
是對物理文件路徑,意味著如果物理文件的路徑發生了改變(比如改變了文件的目錄結構或者文件名),原來該文件連結將變得無效。 - 可讀性:在很多情況下,URL不僅僅需要能夠訪問正確的網絡資源,也需要具有很好的可讀性,最好的URL應該讓我們一眼就能看出針對它訪問的目標資源是什麼。請求地址與物理文件緊密綁定讓我們完全失去了定義高可讀性URL的機會。
- SEO優化:對於網站開發來說,為了迎合搜索引擎檢索的規則,我們需要對URL進行有效的設計使之能易於被主流的引擎檢索收錄。如果URL完全與物理地址關聯,這失去了SEO優化的能力。
- 安全性:如接指向文件相對路徑無疑跟大家說你伺服器資料夾的結構,如果被有心人士(黑客)知道就可旁敲側擊攻擊您的伺服器.
RouteTable.Routes
在Global.cs檔案中,有一個RouteTable.Routes
是RouteCollection
類型的集合物件
我們通過RouteTable
靜態屬性Routes
得到一個全域的路由表,路由註冊的核心價值在此集合上添加路由設定。
1 | RouteConfig.RegisterRoutes(RouteTable.Routes); |
RouteCollection
他是繼承Collection<RouteBase>
的集合物件,可以對此集合添加一個繼承RouteBase
物件.
在Mvc一般是透過MapRoute
擴展方法來添加路由
1 | public static void RegisterRoutes(RouteCollection routes) |
MapRoute擴展方法
看一下MapRoute
原始碼,這個方式是基於RouteCollection
集合物件做的擴展方法,可看到最重要的部分是新增一個Route
物件並加入集合中.
1 | public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) |
Route物件
Route
類別是繼承於RouteBase
(這也就是為什麼可以把Route
物件加入RouteCollection
集合中)
下面我刪減一些此次不會介紹到的程式碼.
1 | public class Route : RouteBase |
在Route
類別中GetRouteData
是個重要方法,藉由我們的路由設定去解析當前是否匹配到路由規則,如果有就回傳一個RouteData
物件,否則回傳Null
上一篇有介紹
UrlRoutingModule
這個HttpModule
會藉由RouteCollection.GetRouteData(context)
動作取得一個RouteData
並透過他拿到IHttpHander
物件並給值到HttpContext.Handler
在裡面的實做是透過一個
foreach
去找尋匹配的Route
物件,因為ADD
路由是有順序性,所以在RegisterRoutes(RouteCollection routes)
找尋路由會有第一個MapRoute
到最後一個
Url
這個屬性的set
方法上做一個很有意思的動作,在設定值時除了賦值給_url
字段,另外還將 設定template url Parse 取得一個ParsedRoute _parsedRoute
物件.
ParsedRoute
將我們注冊的template url用/
分割存起來方便日後判斷執行的Action
和Contoller
.
MapPageRoute 擴展方法
路由除了使用於取得調用Contoller
和Action
資訊外,我們還可以通過MapPageRoute
註冊URL樣板和某種文件的配對關係.
範例在:Asp.net MVC Debugger
本次使用幾個參數
- 路由名稱
- 樣版URL
- 指向實體
aspx
檔案路徑 - 此路由是否找尋實體路徑
- 樣版URL預設參數
1 | routes.MapPageRoute( |
下圖是我們專案建立一個新的.aspx
檔案
裡面內容很簡單只是印出一段文字
1 | Hello PhysicalFile.aspx |
因為有加入MapPageRoute
路由,在瀏覽器網址列輸入http:localhost:[your port]/GetFile
,我們就可以將PhysicalFile.aspx
檔案內容顯示出來.
在 Route中建立處理客製化HttpHandler
在Route
建構子中我們可以設定實現IRouteHandler
物件,這個物件會有個方法可以返回IHttpHandler
給asp.net
請求使用.
1 |
|
我們可以建立MyHandlerRouter
在GetHttpHandler
返回一個MyHandler
物件,之後把MyHandlerRouter
當作參數傳入Route
物件中
把Route
加入全域路由集合中
1 | routes.Add(new Route("Customer",new MyHandlerRouter())); |
在瀏覽器輸入
http://localhost:[your port]/Customer
我們就會執行我們自己客製化的HttpHandler
小結:
路由封裝了Http請求路徑資訊可以讓我們找到相對應的Action
和Controller
並呼叫執行外,可以透過MapPageRoute
來將請求教給.aspx
實體檔案來處理請求.
Route
甚至可以讓我們自己客製化處理HttpHandler
如 在 Route中建立處理客製化HttpHandler可謂很有彈性
下篇介紹Route
物件建立MvcRouteHandler
物件如何取到IHttpHandler
.
此文作者:Daniel Shih(石頭)
此文地址: https://isdaniel.github.io/ithelp-day9/
版權聲明:本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 3.0 TW 許可協議。轉載請註明出處!