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  許可協議。轉載請註明出處!