ASP.NET MVC Moduleweb
在ASP.NET中管道模型是怎麼來實現的?在請求處理流程一文中大概的講述了Http Module和HttpApplication之間的關係,而並無涉及到Http Module怎麼去實現和註冊。Http Module的意義很大,ASP.NET MVC框架怎麼捕獲請求的?或者換一種方式來講ASP.NET MVC框架的入口點在哪裏?app
咱們直接進入主題來看一下自定義的實現,首先在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的事件,在請求處理流程文中說過,這裏不做講解了。spa
這個時候運行程序是不行的,ASP.NET有天大的本事也不知道你本身自定義了一個Module的阿,你得告訴它我這有個自定義的Module,運行的時候要執行個人這個Module。code
如今咱們來把Module註冊到系統中,打開項目中的Web.config配置文件,找到<system.web>節點添加<httpModules>節點.對象
代碼1-2blog
<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框架的項目,因此要添加一個空的控制器和一個視圖。
這樣咱們再看一下項目的運行結果:
圖1
這裏要說的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 }
在上面的代碼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/
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面