ASP.NET MVC Controller激活系統詳解2

一.引言

                  此篇博文緊接上篇博文進行闡述,本篇博文闡述的主題是Controller激活和url路由web

二.總述

                  ASP.NET路由系統是HTTP請求抵達服務端的第一道屏障,它根據註冊的路由規則對攔截的請求進行匹配並解析包含目標的Controller和Action名稱的路由信息。當前ControllerBuilder具備用於激活Controller對象的ControllerFactory。app

                  ASP.NET路由系統的核心是一個叫作UrlRoutingModule的自定義HttpModule,路由的實現是它經過註冊表明當前web應用的HttpApplication的PostResolverRequestCache事件對HttpHandler的動態映射來實現的。具體來講,它經過以RouteTable的靜態屬性Routes表明的全局路由表對請求進行匹配並獲得一個RouteData對象。RouteData具備一個實現了接口IRouteHandler屬性RouteHandler,經過該屬性的GetHttpHandler獲得最終被映射到當前請求的HttpHandler。函數

       三.MVC

                  對於MVC應用來講,RouteData的RouteHandler屬性類型爲MvcRouteHandler,體如今MvcRouteHandler類型上關於HttpHandler的提供機制基本上(不是徹底等同)能夠經過以下的代碼來表示。MvcRouteHandler維護着一個ControllerFactory對象,該對象能夠在構造函數中指定,若是沒有顯示指定則直接經過調用當前ControllerBuilder的GetControllerFactory來獲取。ui

 1     public class MvcRouteHandler:IRouteHandler
 2     {
 3         private IControllerFactory _controllerFactory;
 4 
 6         public MvcRouteHandler() { }
 7         public MvcRouteHandler(IControllerFactory controllerFactory)
 8         {
 9             _controllerFactory = controllerFactory;
10         }
11 
12         protected virtual SessionStateBehavior GetSessionStateBehavior(RequestContext context)
13         {
14             string str = (string)context.RouteData.Values["controller"];   //RouteData.Values獲取路由的url參數值和默認值的集合
15             if(string.IsNullOrWhiteSpace(str))
16             {
17                 throw new InvalidOperationException("MvcRouteHandler_RouteValuesHasNoController");
18             }
19             IControllerFactory factory = _controllerFactory ?? ControllerBuilder.Current.GetControllerFactory();
20             return factory.GetControllerSessionBehavior(context, str);
21         }
22         public virtual IHttpHandler GetHttpHandler(RequestContext context)
23         {
24             context.HttpContext.SetSessionStateBehavior(GetSessionStateBehavior(context));
25             return new MvcHandler(context);
26         }
27     }

                  用於提供HttpHandler的GetHttpHandler方法中,除了返回一個實現了IHttpHandler接口的MvcHandler對象以外,還須要對當前Http上下文的會話狀態行爲模式進行設置。具體來講,首先經過包含在傳入RequestContext的RouteData對象獲得Controller的名稱,該名稱連同RequestContext對象一塊兒傳入ControllerFactory的GetControllerSessionBehavior方法獲得一個類型爲SessionStateBehavior的枚舉。最後經過RequestContext獲得表示當前HTTP上下文的HttpContextBase對象(其實是一個HttpContextWrapper對象)並調用其SetSessionStateBehavior方法。url

                  咱們知道RouteData中的RouteHandler屬性最初來源於對應的Route對象的同名屬性,而當咱們調用RouteCollection的擴展方法MapRoute方法時,其內部會直接建立並添加一個Route對象。因爲在建立Route對象是並無顯式指定ControllerFactory,因此經過當前ControllerBuilder的GetControllerFactory方法獲得的ControllerFactory默認被使用。spa

                  經過當前ControllerBuilder的GetControllerFactory方法獲得的ControllerFactory僅僅用於獲取會話狀態行爲模式,而MvcHandler真正將它用於建立Controller。MvcHandler中關於對請求處理的邏輯基本上能夠經過以下的代碼片段來體現。以下面的代碼片段所示,MvcHandler具備一個表示當前請求上下文的RequestContext屬性,該屬性在構造函數中被初始化。code

相關文章
相關標籤/搜索