Agenda
前言 前一篇介紹路由封裝了Http請求路徑資訊可以讓我們找到相對應的Action
和Controller
並呼叫執行外,也可透過MapPageRoute
來將請求教給.aspx
實體檔案來處理請求.
Route
甚至可以讓我們自己客製化處理HttpHandler
在Route中建立處理客製化HttpHandler可謂很有彈性
本篇介紹Route
物件建立MvcRouteHandler
物件且如何取到IHttpHandler
.
我有做一個可以針對於Asp.net MVC Debugger 的專案,只要下中斷點就可輕易進入Asp.net MVC原始碼.
MVC取得使用HttpHandler (IHttpHandler) 之前說到我們透過MapRoute
擴展方法加入一個Route
物件給RouteCollection
全域路由集合 .
在Route
使用的IRouteHandler
介面是由MvcRouteHandler
來實現
1 2 3 4 5 6 Route route = new Route(url, new MvcRouteHandler()) { Defaults = CreateRouteValueDictionaryUncached(defaults), Constraints = CreateRouteValueDictionaryUncached(constraints), DataTokens = new RouteValueDictionary() };
IRouteHandler
最重要的是IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext)
會取得一個IHttpHandler
物件.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public class MvcRouteHandler : IRouteHandler { private IControllerFactory _controllerFactory; public MvcRouteHandler () { } public MvcRouteHandler (IControllerFactory controllerFactory ) { _controllerFactory = controllerFactory; } protected virtual IHttpHandler GetHttpHandler (RequestContext requestContext ) { requestContext.HttpContext.SetSessionStateBehavior(GetSessionStateBehavior(requestContext)); return new MvcHandler(requestContext); } protected virtual SessionStateBehavior GetSessionStateBehavior (RequestContext requestContext ) { string controllerName = (string )requestContext.RouteData.Values["controller" ]; if (String.IsNullOrWhiteSpace(controllerName)) { throw new InvalidOperationException(MvcResources.MvcRouteHandler_RouteValuesHasNoController); } IControllerFactory controllerFactory = _controllerFactory ?? ControllerBuilder.Current.GetControllerFactory(); return controllerFactory.GetControllerSessionBehavior(requestContext, controllerName); } #region IRouteHandler Members IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext) { return GetHttpHandler(requestContext); } #endregion }
上面程式碼可以看到Mvc 使用IHttpHandler
是MvcHandler
MVC呼叫的HttpHandler (MvcHandler) MvcHandler
類別中主要核心的程式碼做了幾件事情.
使用一個Adapter
對於HttpContext
物件把他轉成可以繼承於HttpContextBase
的HttpContextWrapper
類別.
透過ProcessRequestInit
取得執行controller
物件並且呼叫執行方法.
最後透過ReleaseController
釋放之前使用過資源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 protected virtual void ProcessRequest (HttpContext httpContext ){ HttpContextBase httpContextBase = new HttpContextWrapper(httpContext); ProcessRequest(httpContextBase); } protected internal virtual void ProcessRequest (HttpContextBase httpContext ){ IController controller; IControllerFactory factory; ProcessRequestInit(httpContext, out controller, out factory); try { controller.Execute(RequestContext); } finally { factory.ReleaseController(controller); } }
小結 今天我們知道MVC使用HttpHandler
是MvcHandler
透過並MvcRouteHandler
物件來返回.
下圖簡單展現MVC使用的HttpModule
和HttpHandler
關係
在UrlRoutingMoudule
註冊事件.
取得符合Http請求Route
物件
呼叫MvcRouteHandler
取得MvcHandler
物件
執行MvcHandler
的ProcessReqeust
方法
下面會陸續介紹MVC 是如何取得Controller
物件
__此文作者__:Daniel Shih(石頭) __此文地址__: https://isdaniel.github.io/Ithelp-day10/ __版權聲明__:本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 3.0 TW 許可協議。轉載請註明出處!