閱讀759 返回首頁    go 阿裏雲 go 技術社區[雲棲]


HttpHandler HttpModule入門篇

HttpHandler HttpModule入門篇

ASP.Net處理Http Request時,使用Pipeline(管道)方式,由各個HttpModule對請求進行處理,然後到達 HttpHandlerHttpHandler處理完之後,仍經過Pipeline中各個HttpModule的處理,最後將HTML發送到客戶端瀏覽器中。

生命周期中涉及到幾個非常重要的對象:HttpHandlerHttpModuleIHttpHandlerFactory他們的執行(順序)大致的執行過程是這樣的:

client端發送頁麵請求,被IIS的某個進程截獲,它根據申請的頁麵後綴(.aspx)不同,調用不同的頁麵處理程序(.asp->asp.dll; .aspx->ISAPI.dll)而頁麵處理程序在處理過程中,則要經曆HttpModuleHttpHandler的處理:前者HttpModule用於頁麵處理前和處理後的一些事件的處理,後者HttpHandler進行真正的頁麵的處理。
    如前所說,HttpModule會在頁麵處理前和後對頁麵進行處理,所以它不會影響真正的頁麵請求。通常用在給每個頁麵的頭部或者尾部添加一些信息(如版權聲明)等。曾經見過一些免費的空間,我們的頁麵上傳上去後,瀏覽的時候發現,在每個頁麵的頭部和尾部多了很多小廣告....如果理解了HttpModule的原理,要做這個就不是很難了~

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

 

ASP.Net係統本身配置有很多HttpHandlerHttpModule,以處理aspx.Net標準的頁麵文件,以及這些頁麵文件中標準的事件處理等。查看

%System%/Microsoft.NET/Framework/v2.0.50727/CONFIG目錄下的 web.config文件中的httpHandlershttpModules節點,可以看到這些配置。如果有興趣,可以使用Reflector查看.Net係統中相關的類和方法,了解.Net如何處理以及做了什麼處理。

.Net也提供了一套機製來開發自定義的HttpHandler HttpModule,均可以用於對HttpRequest的截取,完成自定義的處理。 HttpModule 繼承System.Web.IHttpModule接口,實現自己的HttpModule類。必須要實現接口的兩個方法:InitDispose。在 Init中,可以添加需要截取的事件;Dispose用於資源的釋放,如果在Init中創建了自己的資源對象,請在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_objSenderEventArgs r_objEventArgs)

        {

            HttpApplication objApp = (HttpApplication)r_objSender;

            objApp.Response.Write("您請求的URL" + objApp.Request.Path);

        }

    }

將編譯的dll文件拷貝到web項目的bin目錄下,在web項目的web.config文件system.web節點中配置:

    <httpModules>

      <add name="test" type="MyHttpModuleTest.MyHttpModule,MyHttpModule"/>

    </httpModules>
    這樣就將自定義的HttpModuleMyHttpModule插入到了當前webHttpModulePipeline中。 HttpModule主要功能是對Application的各個事件進行截取在這些事件中完成自己的處理。其實如果自己開發一些項目,直接在 Global.asax中處理已經足夠了。如果是開發一個Framework或者是某些方麵的組件,需要在事件中添加處理,開發自定義的 HttpModule,可以避免使用Framework或者組件時,還得手工在Global.asax中添加代碼。目前想到的開發自定義HttpModule的用途,有全局的身份/權限驗證、自定義網站訪問/操作日誌的記錄、處於管理/調試等目的對站點進行監控追蹤等。當然,如果是結合自定義的HttpHandler進行Framework的開發,HttpModule可以用於其它的一些特殊的處理。注意要區分大小寫,因為web.config作為一個XML文件是大小寫敏感的。type=MyHttpModuleTest.MyHttpModule,MyHttpModule告訴我們係統將會將http request請求交給位於MyHttpModule.dll文件中的MyHttpModuleTest.MyHttpModule去處理。HttpHandler是完全的對Http Request的截取。
    首先,繼承System.Web.IHttpHandler接口,實現自己的HttpHandler類。必須要實現接口的ProcessRequest方法和IsReusable屬性。ProcessRequest方法中完成對每個Http Request的處理,發送處理結果的HTML到輸出緩存中。IsReusable屬性被.Net Framework調用,用以確定這個HttpHandler的實例是否可以被重用於同類型其它的Request處理。
    如果你在自己的HttpHandler類中,需要讀取或者是寫Session值,需要再繼承一個接口IRequiresSessionState。這個接口沒有任何方法,隻是一個標記接口。繼承這個接口之後,就可以在自己的HttpHandler中訪問Session,可以在Session中寫入值。

 

namespace MyHandler

{

    public class MyHttpHandler : IHttpHandlerIRequiresSessionState

    {

        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。我們為IIS配置一個以.cc為後綴名的文件類型,用我們寫的MyHttpHandler來處理。
    首先,在IIS站點的Configuration配置裏麵,添加一個對.cc後綴名處理的Application Extention Mapping項。   
    然後,在web項目的web.config節點中配置:

    <httpHandlers>

      <add verb="*" path="*.cc" type="MyHandler.MyHttpHandler,MyHandler"/>

    </httpHandlers> 

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

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

    總之,將HttpModuleHttpHandler,以及使用Ajax等將客戶端進行封裝結合起來,能夠給web項目的開發帶來非常大的改善空間。

Asp.Net HttpHandler實現URL重寫的
我們經常看到很多網站訪問文章的時候才用的是***.html ***.shtml 這寫文件在服務器上不存在的,那為什麼會出現這樣的效果呢,是因為Web服務器上對URL執行了重寫,把訪問的 URL根據特定的格式重寫成內部訪問頁麵來實現的,它的好處是便於用戶理解,同時搜索引擎也能更好地收入你的網站,當然其它的好處也很多,這裏不做一一介 紹了。 
本文所講的是使用Asp.Net中的HttpHandler實現URL重寫的,它所實現的原理請看這裏,本程序可以處理任何Url,因為我在程序中使用了URL過慮,隻有訪問文件名是數字的才進行處理,並指在內部執行一個新的頁麵,並輸出數據,代碼如下:

        public void ProcessRequest(HttpContext Context)

        {

            try

            {

                //申明Request        

                HttpRequest Request = Context.Request;

                //取來路Url的絕對路徑       

                string Url = Request.Url.AbsolutePath;

                //取訪問的Web文件的開始字符間隔數

                int RegStart = Url.LastIndexOf("/") + 1;

                //申明一個確定Web文件名是否全是數字

                Regex Reg = new Regex(@"/d+");

                //用正則表達式進行匹配

                if (Reg.IsMatch(UrlRegStart))

                {

                    //如果web文件名是數字,則判定是查詢相關文章,執行指定頁麵

                    Context.Server.Execute("~/PermaLink.aspx?font-family:'Microsoft Sans Serif';font-size:10.5pt;"> + Reg.Match(UrlRegStart).Value);

                }

            }

            catch

            {

                Context.Response.Redirect(Context.Request.Url.ToString());

            }

        }

當然你首先要做的是先建一個類,並繼承自IHttpHandler,然後把這段代碼拷入,並編譯。在Web項目中若要使用此功能,需要在web.config裏麵加上如下語句:

 

      <httpHandlers>

      <add verb="*" path="*.shtml" type="HttpHandle.UrlRewrite" />

</httpHandlers>

同時,還要在IIS中對Web項目進行配置,在Web項目的屬性中,在主目錄選項卡裏,把執行權限改為"腳本和可執行文件",然後打開配置,在應用程序擴展裏加上需重寫的文件格式的擴展。好了,萬事具備,隻欠運行了。

 

最後更新:2017-04-02 06:51:20

  上一篇:go magento -- 新會員首次購物免運費的實現思路
  下一篇:go 深入理解linux下rc.d/目錄文件以及程序開機自啟動