ASP.NET中的Http Handles
2024-07-10 12:57:47
供稿:網友
 
菜鳥學堂: 
一、關于http handles
 asp.net的請求過程是基于一個管道(pipeline)模型的,asp.net會把所有的http請求(requests)都發送給這個管道里的http組件(modules)。每個組件在接收到http請求后進行一些相應的動作。當http請求通過了所有的http modules程序后,將會被交由一個http handle程序來處理,處理后的結果又將通過管道里http modules返回。這整個過程中,被調用的http module可以有多個,然而調用的http handle只能是一個。其過程如圖:
 可以看出每個輸入的http請求都會最終被一個http handle程序處理。http handle是一個實現了system.web.ihttphandler接口的類的實例,有些類似isapi擴展。在http handles中實現的有:
processrequest:該方法用來處理http請求,是http handles最核心的方法
isreusable:一個屬性,返回一個bool值,來表示這http handle的實例是否能被重用來處理多個同類型的http請求。
二、在配置文件中注冊http handles
 http handles的類可以在web.config或machine.config文件里注冊。這樣,一旦有相應的http請求輸入,這個http handle類就會被實例化。在web.config或machine.config文件里我們用<httphandlers>和<add>節點來為我們的應用程序添加http handle類:
<httphandlers>
 <add verb="supported http verbs" path="path" type="namespace.classname, assemblyname" />
<httphandlers>
在<add>里
1、verb屬性說明了該handle所支持的http請求方式,例如支持post和get方式,verb屬性則為"post,get";如果支持所有的請求方式,verb屬性則用"*"。
2、path屬性說明了對哪些文件的請求才調用該handle來處理,例如你只想在請求my.possible文件時才調用該handle,則path屬性為"my.possible",如果你想所有后綴名為possible的文件(*.possible)都由該handle來處理,則path屬性為"*.possible"。
3、type屬性中指定了handle類的命名空間、類名和配件名(工程名)。asp.net runtime會首先到應用程序的bin目錄下查找該配件的dll,如果沒有找到再到gac里查找。
其實asp.net自身里的許多功能也是使用http handlers來實現,asp.net使用了許多的handle類來處理.aspx, .asmx, .soap 和一些其它的asp.net文件。你可以在machine.config文件里找到如下代碼:
<httphandlers>
<add verb="*" path="trace.axd" type="system.web.handlers.tracehandler"/>
 
 <add verb="*" path="*.aspx" type="system.web.ui.pagehandlerfactory"/>
 
 <add verb="*" path="*.ashx" type="system.web.ui.simplehandlerfactory"/>
 <add verb="*" path="*.config" type="system.web.httpforbiddenhandler"/>
 
 <add verb="get,head" path="*" type="system.web.staticfilehandler"/>
 
 . . . . . . 
 . . . . . .
</httphandlers>
從上面的配置可以看出來對.aspx文件的請求是交由system.web.ui.pagehandlerfactory類來處理的,而象.config文件是被system.web.httpforbiddenhandler類來處理,可以猜想這個類將會返回一個該類文件不能被請求的錯誤。
三、http handles類的實現
 在這里我們用c#來創建一個新的handle類來處理新的文件類型,比如以.possible為后綴名的文件。
1、我們先在vs.net里創建web應用程序的工程,名為myhandler,然后添加一個類文件newhandler.cs來建立實現了ihttphandler接口的類:
using system;
using system.web;
namespace myhandler
{
 /// <summary>
 /// summary description for newhandler.
 /// </summary>
 public class newhandler : ihttphandler
 {
 public newhandler()
 {
 //
 // todo: add constructor logic here
 //
 }
 #region implementation of ihttphandler
 public void processrequest(system.web.httpcontext context)
 {
 httpresponse objresponse = context.response ;
 objresponse.write("<html><body><br><br><center>hi,this is a test! ") ;
 objresponse.write("</center></body></html>") ;
 }
 public bool isreusable
 {
 get
 {
 return true;
 }
 }
 #endregion
 }
}
在processrequest方法的實現里,我們只是簡單的獲取了httpcontext的httpresponse對象,并象客戶端發送了一些html。在isreusable的實現里返回true,表示該handle類的實例可以處理多個對.possible文件的請求。
注意:如果想在http handlers里使用session,那么還需要實現irequiressessionstate接口,而irequiressessionstate接口只是一個標志,不需要實現任何的具體方法,所以只需要把類申明改為:public class newhandler : ihttphandler,irequiressessionstate即可。
2、打開web.config文件,注冊上面新創建的handle類:
<httphandlers>
 <add verb="*" path="*.possible" type="myhandler.newhandler,myhandler"/>
</httphandlers>
3、在iis中添加isapi擴展,將我們的新后綴名.possible添加進去,具體過程為:
iis--》選中“默認網站”點右鍵--》選“屬性”--》“主目錄”--》“配置”--》點“映射”里的“添加”按鈕--》在彈出對話框里點擊“瀏覽”按鈕,選擇aspnet_isapi.dll文件,并在擴展名里填possible,如下圖所示:
最后點擊確定按鈕。
這樣我們就可以在瀏覽器里輸入http://localhost/myhandler/xxx.possible,來調用該handle了。當然我們這里只是舉了個簡單例子,所以輸入任何*.possible都是一樣的效果。我們可以在newhandler的processrequest方法里先分析請求的url,然后根據不同url作出不同的相應,比如跳轉到不同的真實存在的aspx頁面,這也正是web設計模式中mvc模式在asp.net中通過front controller實現的核心部分之一,具體請見:http://msdn.microsoft.com/architecture/patterns/default.aspx?pull=/library/en-us/dnpatterns/html/desfrontcontroller.asp。