ASP.NET Framework深度歷險(2)
發表于:2007-06-30來源:作者:點擊數:
標簽:
剛剛吃完晚飯,正好在鍵盤上面鍛煉一下手指。 接著上回繼續寫這個“日記”: Chapter Two -- HttpModule是如何工作的? 我們上回說到,一個來自于客戶端的Http Request被截獲后經過層層轉交(怎么都在踢皮球?呵呵)到達了HttpModule這個“請求監聽器”。 Ht
剛剛吃完晚飯,正好在鍵盤上面鍛煉一下手指。
接著上回繼續寫這個“日記”:
Chapter Two -- HttpModule是如何工作的?
我們上回說到,一個來自于客戶端的Http Request被截獲后經過層層轉交(怎么都在踢皮球?呵呵)到達了HttpModule這個“請求監聽器”。
HttpModule就類似于安插在ASPNET_WP.EXE進程中的一個竊聽器,稍微有些常識的人都會很自然的想象得到竊聽器是用來做什么的,而我們的HttpModule
可以說是作竊聽器的絕好人選了,但是需要明確的是,HttpModule絕對不是簡單的監聽器,它可以做到更多的東西,比如它可以對截獲的請求增加一些內容
等等。
另外需要明白的是,當一個Http Request到達HttpModule的時候,整個ASP.NET Framework系統還并沒有對這個請求做任何的真正處理,但是我們可以
在這個Http Request傳遞到真正的請求處理中心(HttpHandler)之前附加一些我們需要的信息在這個Http Request至上,或者針對我們截獲的這個Http
Request信息作一些額外的工作,或者在某些情況下干脆終止滿足一些條件的Http Request,從而可以起到一個Filter過濾器的作用,而不僅僅是一個竊聽器了。
通過查閱MSDN(不要去相信.NET SDK自帶的那個QuickStarts Web文檔,正式版本中竟然在很多地方沒有更新這個文檔,很多東西在正式版本是無效的),
你會發現系統HttpModule實現了一個叫做IHttpModule的接口,很自然的就應當想到,只要我們自己的類能夠實現IHttpModule接口,不就可以完全替代系統的
HttpModule了嗎?完全正確。
在我們開始自己的HttpModule類之前,我先來告訴你系統中的那個HttpModule是什么樣子的,ASP.NET系統中默認的HttpModule有以下幾個:
System.Web.Caching.OutputCacheModule
System.Web.SessionState.SessionStateModule
System.Web.Security.
WindowsAuthenticationModule
System.Web.Security.FormsAuthenticationModule
System.Web.Security.PassportAuthenticationModule
System.Web.Security.UrlAuthorizationModule
System.Web.Security.FileAuthorizationModule
好了,我們來開始我們自己的HttpModule構建歷程吧。
1)打開VS.NET新建一個“Class Library”項目,將它命名為MyHttpModule。
2)引用System.Web.dll文件
在代碼區域敲入:
using System;
using System.Web;
namespace MyHttpModuleTest
{
/// <summary>
/// 說明:用來實現自定義HttpModule的類
/// 作者:uestc95
/// 聯系:uestc95@263
.net
/// </summary>
public class MyHttpModule:IHttpModule
{
/// <summary>
/// 說明:構造器方法
/// 作者:uestc95
/// 聯系:uestc95@263.net
/// </summary>
public MyHttpModule()
{
}
/// <summary>
/// 說明:實現IHttpModule接口的Init方法
/// 作者:uestc95
/// 聯系:uestc95@263.net
/// </summary>
/// <param name="application">HttpApplication類型的參數</param>
public void Init(HttpApplication application)
{
application.BeginRequest +=new EventHandler(this.Application_BeginRequest);
application.EndRequest +=new EventHandler(this.Application_EndRequest);
}
/// <summary>
/// 說明:自己定義的用來做點事情的私有方法
/// 作者:uestc95
/// 聯系:uestc95@263.net
/// </summary>
/// <param name="obj">傳遞進來的對象參數</param>
/// <param name="e">事件參數</param>
private void Application_BeginRequest(Object obj,EventArgs e)
{
HttpApplication application=(HttpApplication)obj;
HttpContext context=application.Context;
HttpResponse response=context.Response;
HttpRequest request=context.Request;
response.Write("我來自Application_BeginRequest,:)");
}
/// <summary>
/// 說明:自己定義的用來做點事情的私有方法
/// 作者:uestc95
/// 聯系:uestc95@263.net
/// </summary>
/// <param name="obj">傳遞進來的對象參數</param>
/// <param name="e">事件參數</param>
private void Application_EndRequest(Object obj,EventArgs e)
{
HttpApplication application=(HttpApplication)obj;
HttpContext context=application.Context;
HttpResponse response=context.Response;
HttpRequest request=context.Request;
response.Write("我來自Application_EndRequest,:)");
}
/// <summary>
/// 說明:實現IHttpModule接口的Dispose方法
/// 作者:uestc95
/// 聯系:uestc95@263.net
/// </summary>
public void Dispose(){}
}
}
3)在VS.NET中編譯之后,你會得到MyHttpModule.dll這個文件。
4)接下來我們的工作就是如何讓ASPNET_WP.exe進程將http request交給我們自己寫的這個HttpModule呢?方法就是配置web.config文件。
在web.config文件中增加如下幾句話:
<httpModules>
<add name="test" type="MyHttpModuleTest.MyHttpModule,MyHttpModule"/>
</httpModules>
注意要區分大小寫,因為web.config作為一個XML文件是大小寫敏感的?!皌ype=MyHttpModuleTest.MyHttpModule,MyHttpModule”告訴我們
系統將會將http request請求交給位于MyHttpModule.dll文件中的MyHttpModuleTest.MyHttpModule類去處理。而這個DLL文件系統將會自動
到\bin子目錄或者系統全局程序集緩沖區(GAC)搜尋。我們可以將我們剛才得到的DLL文件放在bin子目錄中,至于后者,你可以通過.NET SDK正式版
自帶的Config工具做到,我們不詳細說了。
好了,我們的用來截獲http request請求的HttpModule就完成并且裝配完成了,你可以試著在你的web項目中建立一個新的WebForm,運行看看呢?:)
最后,我們假設一個使用這個HttpModule的場合。A站點提供免費的ASP.NET虛擬空間給大家,但是A站點的管理者并不想提供免費的午餐,他想要在每一個
頁面被瀏覽的時候自動彈出自己公司的廣告(就像現在的www.X63.com一樣),我總不能時刻監視所有用戶的所有頁面吧,并且想要在每一個頁面手動添加
一段JS代碼,工作量是不可想象的,也是不現實的。那末好了,只要我們的HttpModule一旦被掛接完成,這一切都將是輕而易舉的事情了,只要我們在每一個
Http Request被我們捕獲的時候,給他增加上一些JS就好了!
我們上面提到在Init()方法中使用了兩個事件BeginRequest和EndRequest,這兩個事件分別是Init()中可以處理的所有事件的最開始事件和最終事件,在他們
中間還有一些其它的事件可以被我們利用,可以查閱MSDN。
另外在我關閉EditPlus之前,需要敲下如下的話:
在HttpModule中可以正常使用Response,Request,Server,Application,但是不能操作任何與Session有關代碼!
為什么呢?自己考慮一下吧,下回看看原因在哪里,另外再給出一個問題,你能發現系統默認的那幾個HttpModule在哪里配置的呢?找找看。
下回我們看看HttpHandler部分以及如何同HttpModule相配合的東東。
See you later.
原文轉自:http://www.kjueaiud.com