ASP.NET MVC Module

weixin_33763244發表於2017-11-09


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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 1     public class CustomModule:IHttpModule
 2     {
 3         public void Dispose()
 4         {
 5             throw new NotImplementedException();
 6         }
 
 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

1
2
3
4
5
<system.web>
    <httpModules>
      <add name="MyCustomModule" type="MvcApplication.CustomModule,MvcApplication"/>
    </httpModules>
 </system.web>

這裡要說的是Name屬***&ldquo;MyCustomModule&rdquo;值只是Module註冊到系統的名稱,可通過HttpApplication例項物件.Modules["MyCustomModule"]的方式根據Name獲取到已經註冊到系統中的Module

Type屬***值則為自定義的CustomModule型別所在的名稱空間已經型別名稱,逗號後面的值為CustomModule型別所在的程式集名稱。

 

這個時候還是不能執行程式的,因為博主的示例程式是使用MVC框架的專案,所以要新增一個空的控制器和一個檢視。

 

  1. 右擊Controllers資料夾新增->控制器,設定名稱為HomeController,設定控制器模板為空控制器,單擊確定後,會看到控制器中有個預設的Index()方法。

  2. 右擊Index()方法名稱,選擇新增檢視後彈出對話方塊點選新增即可。

  3. 新增 <h2>自定義Module演示</h2><hr /> 到檢視

這樣我們再看一下專案的執行結果:

圖1

UrlRoutingModule

這裡要說的UrlRoutingModule型別就是一個系統定義的Module,為什麼要講解它呢?因為從它裡面可以看到系統的擴充套件點,也因為它是路由系統和MVC框架的連線點。

根據前面的篇幅對於路由的學習,可以說是對路由有了一個基礎的認識,大家都知道請求的Url會去匹配系統的定義的路由模式,然後獲得一個RouteData這麼一個物件例項,然後根據它裡面的資訊來進行對控制器的生成操作等等後續的一些行為。

我們來看圖1來理解UrlRoutingModule的作用,或許在實際專案開發中不會自己去擴充套件這部分內容,但是多瞭解一下也沒有壞處。

圖2

UrlRoutingModule型別的內部大概實現如程式碼1-3

程式碼1-3

1
2
3
4
5
6
7
8
9
10
11
 1         void context_PostResolveRequestCache(object sender, EventArgs e)
 2         {
 3             HttpApplication context = sender as HttpApplication;
 4             HttpContextWrapper contextWrapper = new HttpContextWrapper(context.Context);
 
 6             RouteData routeData = RouteTable.Routes.GetRouteData(contextWrapper);
 
 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框架中請求->路由->控制器的一個過程。這部分內容會在控制器部分說明。




     本文轉自jinyuan0829 51CTO部落格,原文連結:http://blog.51cto.com/jinyuan/1423998,如需轉載請自行聯絡原作者







相關文章