ASP.NET MVC Module
前言
在ASP.NET中管道模型是怎么來實現的?在請求處理流程一文中大概的講述了Http Module和HttpApplication之間的關系,而並沒有涉及到Http Module怎么去實現和注冊。Http Module的意義很大,ASP.NET MVC框架怎么捕獲請求的?或者換一種方式來說ASP.NET MVC框架的入口點在哪里?
Http Module注冊使用
我們直接進入主題來看一下自定義的實現,首先在Module使用之前我們要先定義個Module,定義很簡單,定義個類型並且實現IHttpModule接口示例代碼1-1
代碼1-1
1 public class CustomModule:IHttpModule 2 { 3 public void Dispose() 4 { 5 throw new NotImplementedException(); 6 } 7 8 public void Init(HttpApplication context) 9 { 10 context.BeginRequest += new EventHandler(context_BeginRequest); 11 context.EndRequest += new EventHandler(context_EndRequest); 12 } 13 14 void context_EndRequest(object sender, EventArgs e) 15 { 16 ((HttpApplication)sender).Context.Response.Write("<h1>請求處理結束后進入自定義Module</h1>"); 17 } 18 19 void context_BeginRequest(object sender, EventArgs e) 20 { 21 ((HttpApplication)sender).Context.Response.Write("<h1>請求處理開始前進入自定義Module</h1><hr>"); 22 } 23 }
這個時候我們自定義的Module就已經定義好了,在CustomModule類型的 Init()方法中是訂閱了HttpApplication的事件,在請求處理流程文中說過,這里不作講解了。
這個時候運行程序是不行的,ASP.NET有天大的本事也不知道你自己自定義了一個Module的阿,你得告訴它我這有個自定義的Module,運行的時候要執行我的這個Module。
現在我們來把Module注冊到系統中,打開項目中的Web.config配置文件,找到<system.web>節點添加<httpModules>節點.
代碼1-2
<system.web> <httpModules> <add name="MyCustomModule" type="MvcApplication.CustomModule,MvcApplication"/> </httpModules> </system.web>
這里要說的是Name屬性“MyCustomModule”值只是Module注冊到系統的名稱,可通過HttpApplication實例對象.Modules["MyCustomModule"]的方式根據Name獲取到已經注冊到系統中的Module
Type屬性值則為自定義的CustomModule類型所在的命名空間已經類型名稱,逗號后面的值為CustomModule類型所在的程序集名稱。
這個時候還是不能運行程序的,因為博主的示例程序是使用MVC框架的項目,所以要添加一個空的控制器和一個視圖。
- 右擊Controllers文件夾添加->控制器,設置名稱為HomeController,設置控制器模板為空控制器,單擊確定后,會看到控制器中有個默認的Index()方法。
- 右擊Index()方法名稱,選擇添加視圖后彈出對話框點擊添加即可。
- 添加 <h2>自定義Module演示</h2><hr /> 到視圖
這樣我們再看一下項目的運行結果:
圖1
UrlRoutingModule
這里要說的UrlRoutingModule類型就是一個系統定義的Module,為什么要講解它呢?因為從它里面可以看到系統的擴展點,也因為它是路由系統和MVC框架的連接點。
根據前面的篇幅對於路由的學習,可以說是對路由有了一個基礎的認識,大家都知道請求的Url會去匹配系統的定義的路由模式,然后獲得一個RouteData這么一個對象實例,然后根據它里面的信息來進行對控制器的生成操作等等后續的一些行為。
我們來看圖1來理解UrlRoutingModule的作用,或許在實際項目開發中不會自己去擴展這部分內容,但是多了解一下也沒有壞處。
圖2
UrlRoutingModule類型的內部大概實現如代碼1-3
代碼1-3
1 void context_PostResolveRequestCache(object sender, EventArgs e) 2 { 3 HttpApplication context = sender as HttpApplication; 4 HttpContextWrapper contextWrapper = new HttpContextWrapper(context.Context); 5 6 RouteData routeData = RouteTable.Routes.GetRouteData(contextWrapper); 7 8 RequestContext requestContext = new RequestContext(contextWrapper, routeData); 9 IHttpHandler httpHandler = routeData.RouteHandler.GetHttpHandler(requestContext); 10 httpHandler.ProcessRequest(context.Context); 11 }
IRouteHandler、IHttpHandler
在上面的代碼1-3中,httpHandler變量是通過RouteData對象下的RouteHandler屬性里的GetHttpHandler()方法來根據請求上下文對象RequestContext獲取的。
這里捎帶一句,關於RequestContext類型(不是對象類型,是參數上下文類型)在MVC后續的學習中會經常見到,這也算是一種開發中的模式吧,RequestContext對象中封裝了HttpContextBase對象和RouteData對象。
接着剛才的話題,MvcRouteHandler類型已經實現了IRouteHandler類型,細心的朋友在閱讀前面的文章會發現,在MVC中注冊路由的時候為每個自定義路由規則(也就是Route對象)實例化的時候是用默認的MvcRouteHandler類型,從而會轉變到RouteData的RouteHandler屬性里,在MvcRouteHandler類型的默認實現里,GetHttpHandler()方法返回的是MvcHandler,然后就像上面所說的那樣。在IHttpHandler接口中定義了一個ProcessRequest()方法,這個方法就是MVC框架中請求->路由->控制器的一個過程。這部分內容會在控制器部分說明。
作者:金源
出處:http://www.cnblogs.com/jin-yuan/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面