HttpHandler和HttpModule--入門
          ASP.Net處理Http Request時,使用Pipeline(管道)方式,由各個HttpModule對請求進行處理,然后到達 HttpHandler,HttpHandler處理完之后,仍經(jīng)過Pipeline中各個HttpModule的處理,最后將HTML發(fā)送到客戶端瀏覽 器中。

          生命周期中涉及到幾個非常重要的對象:HttpHandler,HttpModule,IHttpHandlerFactory,他們的執(zhí)行(順序)大致的執(zhí)行過程是這樣的:client端發(fā)送頁面請求,被IIS的某個進程截獲,它根據(jù)申請的頁 面后綴(.aspx)不同,調(diào)用不同的頁面處理程序(.asp->asp.dll; .aspx->ISAPI.dll).而頁面處理程序在處理過程中,則要經(jīng)歷HttpModule,HttpHandler的處理:前者HttpModule用于頁面處理前和處理后的一些事件的處理,后者HttpHandler進行真正的頁面的處理。
          如前所說,HttpModule會在頁面處理前和后對頁面進行處理,所以它不會影響真正的頁面請求。通常用在給每個頁面的頭部或者尾部添加一些信息(如版 權(quán)聲明)等.曾經(jīng)見過一些免費的空間,我們的頁面上傳上去后,瀏覽的時候發(fā)現(xiàn),在每個頁面的頭部和尾部多了很多小廣告....,如果理解了 HttpModule的原理,要做這個就不是很難了~


          IHttpModule與IHttpHandler的區(qū)別整理
            1.先后次序.先IHttpModule,后IHttpHandler. 注:Module要看你響應(yīng)了哪個事件,一些事件是在Handler之前運行的,一些是在Handler之后運行的
            2.對請求的處理上:
            IHttpModule是屬于大小通吃類型,無論客戶端請求的是什么文件,都會調(diào)用到它;例如aspx,rar,html的請求.
            IHttpHandler則屬于挑食類型,只有ASP.net注冊過的文件類型(例如aspx,asmx等等)才會輪到調(diào)用它.
            3.IHttpHandler按照你的請求 生成響應(yīng)的內(nèi)容,IHttpModule對請求進行預(yù)處理,如驗證、修改、過濾等等,同時也可以對響應(yīng)進行處理



          ASP.Net系統(tǒng)本身配置有很多HttpHandler和HttpModule,以處理aspx等.Net標(biāo)準(zhǔn)的頁面文件,以及這些頁面文件中標(biāo) 準(zhǔn)的事件處理等。查看%System%/Microsoft.NET\Framework\v2.0.50727\CONFIG目錄下的 web.config文件中的httpHandlers和httpModules節(jié)點,可以看到這些配置。如果有興趣,可以使用Reflector查 看.Net系統(tǒng)中相關(guān)的類和方法,了解.Net如何處理以及做了什么處理。

          .Net也提供了一套機制來開發(fā)自定義的HttpHandler和 HttpModule,均可以用于對HttpRequest的截取,完成自定義的處理。 HttpModule 繼承System.Web.IHttpModule接口,實現(xiàn)自己的HttpModule類。必須要實現(xiàn)接口的兩個方法:Init和Dispose。在 Init中,可以添加需要截取的事件;Dispose用于資源的釋放,如果在Init中創(chuàng)建了自己的資源對象,請在Dispose中進行釋放。

          namespace MyModule
          {
          public class MyHttpModule : IHttpModule
          {
            public MyHttpModule()
            {
            }

             
            //Init方法用來注冊HttpApplication 事件。
            public void Init(HttpApplication r_objApplication)
            {
            r_objApplication.BeginRequest += new EventHandler(this.BeginRequest);
            }  


          public void Dispose()
            {
            }  

          private void BeginRequest(object r_objSender, EventArgs r_objEventArgs)
            {
            HttpApplication objApp = (HttpApplication)r_objSender;
            objApp.Response.Write("您請求的URL為" + objApp.Request.Path);
            }
          }


          }  

          將編譯的dll文件拷貝到web項目的bin目錄下,在web項目的web.config文件system.web節(jié)點中配置: 
            這樣就將自定義的HttpModule類MyHttpModule插入到了當(dāng)前web的HttpModule的Pipeline中。 HttpModule主要功能是對Application的各個事件進行截取,在這些事件中完成自己的處理。其實如果自己開發(fā)一些項目,直接在 Global.asax中處理已經(jīng)足夠了。如果是開發(fā)一個Framework或者是某些方面的組件,需要在事件中添加處理,開發(fā)自定義的 HttpModule,可以避免使用Framework或者組件時,還得手工在Global.asax中添加代碼。 目前想到的開發(fā)自定義HttpModule的用途,有全局的身份/權(quán)限驗證、自定義網(wǎng)站訪問/操作日志的記錄、處于管理/調(diào)試等目的對站點進行監(jiān)控追蹤 等。當(dāng)然,如果是結(jié)合自定義的HttpHandler進行Framework的開發(fā),HttpModule可以用于其它的一些特殊的處理。


          HttpHandler是完全的對Http Request的截取。
            首先,繼承System.Web.IHttpHandler接口,實現(xiàn)自己的HttpHandler類。必須要實現(xiàn)接口的ProcessRequest方 法和IsReusable屬性。ProcessRequest方法中完成對每個Http Request的處理,發(fā)送處理結(jié)果的HTML到輸出緩存中。IsReusable屬性被.Net Framework調(diào)用,用以確定這個HttpHandler的實例是否可以被重用于同類型其它的Request處理。
            如果你在自己的HttpHandler類中,需要讀取或者是寫Session值,需要再繼承一個接口IRequiresSessionState。這個接 口沒有任何方法,只是一個標(biāo)記接口。繼承這個接口之后,就可以在自己的HttpHandler中訪問Session,可以在Session中寫入值。
          namespace MyHandler
          {
          public class MyHttpHandler : IHttpHandler, IRequiresSessionState
          {
            public MyHttpHandler() {}
            public bool IsReusable
            {
            get { return true; }
            }
            public void ProcessRequest(HttpContext context)
            {
            HttpResponse objResponse = context.Response ;
            objResponse.Write(" 
          This request is handled by MyHttpHandler
          ");
            }
          }
          }
            把編譯的dll文件拷貝到web項目的bin目錄下。
            接下來,這樣來測試一下MyHttpHandler。我們?yōu)镮IS配置一個以.cc為后綴名的文件類型,用我們寫的MyHttpHandler來處理。
            首先,在IIS站點的Configuration配置里面,添加一個對.cc后綴名處理的Application Extention Mapping項。  
            然后,在web項目的web.config節(jié)點節(jié)點中配置:

          MyHttpHandler, MyHandler"/>

            verb屬性配置這個HttpHandler處理那些HTTP方法,例如GET、POST等,如果是處理所有方法,就用*。path屬性配置HttpHandler對哪些文件進行處理,例如可以是myfile.cc,如果是處理所有的.cc文件,就用*.cc。
            這樣,這個站點上所有.cc類型文件的訪問,都由MyHttpHandler處理。使用http://localhost/站點虛擬目錄/a.cc訪問測試站點,可以看到測試效果。當(dāng)然,a.cc這個文件在Web服務(wù)器上是并不存在的。

            對HttpHandler的使用,比較典型的有.Net的Web MVC開源項目Maverick。Maverick使用一個Dispatcher類對所有的Http Request進行截取,他以.m作為后綴名向Web服務(wù)器提交請求,在Dispatcher中,將.m的后綴去掉,提取Command Name,然后以這個command name從配置文件中加載處理的flow,形成一個chain,依次對chain上的各個command和view進行處理,對各個command和 view的處理結(jié)果可能會在chain中選擇不同的處理分支,每個處理的Step中將處理結(jié)果的HTML寫入Response的緩存中進行輸出。
            總體來說,Maverick的框架架構(gòu)概念很不錯,但也存在明顯的缺陷,以后有時間再詳細的寫寫它的架構(gòu)和需要改進之處。

            總之,將HttpModule、HttpHandler,以及使用Ajax等將客戶端進行封裝結(jié)合起來,能夠給web項目的開發(fā)帶來非常大的改善空間。

          Asp.Net HttpHandler實現(xiàn)URL重寫的
          我們經(jīng)??吹胶芏嗑W(wǎng)站訪問文章的時候才用的是***.html 或***.shtml (如本blog的日志訪問效果),其時這寫文件在服務(wù)器上不存在的,那為什么會出現(xiàn)這樣的效果呢,是因為Web服務(wù)器上對URL執(zhí)行了重寫,把訪問的 URL根據(jù)特定的格式重寫成內(nèi)部訪問頁面來實現(xiàn)的,它的好處是便于用戶理解,同時搜索引擎也能更好地收入你的網(wǎng)站,當(dāng)然其它的好處也很多,這里不做一一介 紹了。 
          本文所講的是使用Asp.Net中的HttpHandler實現(xiàn)URL重寫的,它所實現(xiàn)的原理請看這里,本程序可以處理任何Url,因為我在程序中使用了URL過慮,只有訪問文件名是數(shù)字的才進行處理,并指在內(nèi)部執(zhí)行一個新的頁面,并輸出數(shù)據(jù),代碼如下:
          public void ProcessRequest(HttpContext Context)
          {  
          try {  
            //申明Request  
          HttpRequest Request = Context.Request; 
          //取來路Url的絕對路徑  
          string Url = Request.Url.AbsolutePath; 
          //取訪問的Web文件的開始字符間隔數(shù)
          int RegStart = Url.LastIndexOf("/") + 1; 
          //申明一個確定Web文件名是否全是數(shù)字
          Regex Reg = new Regex(@"\d+"); 
          //用正則表達式進行匹配 
          if (Reg.IsMatch(Url, RegStart)) 

          // 如果web文件名是數(shù)字,則判定是查詢相關(guān)文章,執(zhí)行指定頁面 Context.Server.Execute("~/PermaLink.aspx?id=" + Reg.Match(Url, RegStart).Value);  
          }  
          }
          catch
          {
            Context.Response.Redirect(Context.Request.Url.ToString()); 
          }
          }
          當(dāng)然你首先要做的是先建一個類,并繼承自IHttpHandler,然后把這段代碼拷入,并編譯。在Web項目中若要使用此功能,需要在web.config里面加上如下語句:
          <httpHandlers>
            <add verb="*" path="*.shtml" type="HttpHandle.UrlRewrite" />
          </httpHandlers>
          同時,還要在IIS中對Web項目進行配置,在Web項目的屬性中,在主目錄選項卡里,把執(zhí)行權(quán)限改為"腳本和可執(zhí)行文件",然后打開配置,在應(yīng)用程序擴展里加上需重寫的文件格式的擴展,好了,成事具備,只欠運行了。

          posted on 2009-01-20 10:16 sanmao 閱讀(375) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           

          常用鏈接

          留言簿(5)

          隨筆分類

          隨筆檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 文山县| 万年县| 通化县| 玛沁县| 莫力| 革吉县| 雅江县| 永春县| 穆棱市| 阳泉市| 惠来县| 新竹县| 津市市| 昌都县| 庆安县| 荔波县| 黎城县| 保德县| 宁乡县| 桐柏县| 南阳市| 福清市| 涟源市| 丰都县| 易门县| 潮安县| 寿宁县| 壶关县| 女性| 台北市| 青海省| 宜良县| 赤峰市| 龙里县| 绍兴县| 乡宁县| 乳山市| 娱乐| 铜陵市| 靖安县| 金秀|