ASP.NET對請求處理的過程:
HttpRequest-->inetinfo.exe-->ASPNET_ISAPI.dll-->ASPNET_WP.exe-->HttpRuntime-->HttpApplication Factory-->HttpApplication-->HttpModule-->HttpHandler Factory-->HttpHandler-->HttpHandler.ProcessRequest()
通過流程圖, 我們可以看到, 在asp.net請求管道中, httpmodule處理管道內之前和之後的工作, 中間真正的處理由aspx或者ashx等進行.如前所說,HttpModule會在頁面處理前和後對頁面進行處理,所以它不會影響真正的頁面請求。通常用在給每個頁面的頭部或者尾部添加一些資訊(如著作權聲明)等. 或者多語言, 許可權等等工作.
建立一個MyHttpModule和MyHttpHandler, 代碼如下
在MyHttpModule中的初始化方法中註冊以下事件
public void Init(System.Web.HttpApplication application)
{
application.BeginRequest += new EventHandler(application_BeginRequest);
application.EndRequest += new EventHandler(application_EndRequest);
application.PreRequestHandlerExecute += new EventHandler(application_PreRequestHandlerExecute);
application.PostRequestHandlerExecute += new EventHandler(application_PostRequestHandlerExecute);
application.ReleaseRequestState += new EventHandler(application_ReleaseRequestState);
application.AcquireRequestState += new EventHandler(application_AcquireRequestState);
application.AuthenticateRequest += new EventHandler(application_AuthenticateRequest);
application.AuthorizeRequest += new EventHandler(application_AuthorizeRequest);
application.ResolveRequestCache += new EventHandler(application_ResolveRequestCache);
application.PreSendRequestHeaders += new EventHandler(application_PreSendRequestHeaders);
application.PreSendRequestContent += new EventHandler(application_PreSendRequestContent);
}
每個事件的代入類似如下
void application_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
application.Context.Response.Write("application_BeginRequest<br/>");
}
MyHttpHandler
public void ProcessRequest(System.Web.HttpContext context)
{
context.Response.ContentType = "text/html";
context.Response.Write("處理所有的請求");
}
WebConfig中註冊她們
<httpModules>
<add name="MyHttpModule" type="TestModule.MyHttpModule,TestModule"/>
</httpModules>
<httpHandlers>
<add verb="*" path="*" type="TestModule.MyHttpHandler,TestModule"/>
</httpHandlers>
httpmodule可以註冊多個. 管道的處理順序由註冊的先後順序決定
命名 httpmodule , name:類名, type: 程式集.類名,程式集
httphandler, verb:訪問方式(*,get,post), path:處理的尾碼名(*,*.aspx,*.ashx)
請求http://localhost:10153/WebForm1.aspx
輸出application_BeginRequest
global_Application_BeginRequest
application_AuthenticateRequest
global_Application_AuthenticateRequest
application_AuthorizeRequest
application_ResolveRequestCache
application_AcquireRequestState
application_PreRequestHandlerExecute
處理所有的請求application_PostRequestHandlerExecute
application_ReleaseRequestState
application_EndRequest
application_PreSendRequestHeaders
可見.aspx的請求被我們自己構造的handler處理了. 而httpmodule在處理管道的首尾加上了一些東西. 這時候我們反過頭來看看流程圖, 就清晰很多了.
Ihttphandlerfactory介面
介面用於建立和管理處理請求的 HTTP 處理常式。因此,可以建立一個實現 IHttpHandlerFactory 介面的類,然後將該類用作 HTTP 處理常式。
通過這種方式建立處理常式可以使您更好地控制對 HTTP 要求的處理。使用這種方式可以將 URL 對應到基於一組條件建立不同處理常式的 HTTP 處理常式工廠。例如,通過使用 HTTP 處理常式工廠,可以建立有限數量的 HTTP 處理常式對象,來訪問諸如資料庫連接等昂貴或有限的資源。然後,可以在以後的請求中重用這些處理常式對象。
介面方法如下
名稱 |
說明 |
GetHandler |
返回實現 IHttpHandler 介面的類的執行個體。 |
ReleaseHandler |
使工廠可以重用現有的處理常式執行個體。 |
class HandlerFactory:System.Web.IHttpHandlerFactory
{
public System.Web.IHttpHandler GetHandler(System.Web.HttpContext context, string requestType, string url, string pathTranslated)
{
IHttpHandler handlerToReturn = null;
if ("get" == context.Request.RequestType.ToLower())
handlerToReturn = new MyHttpHandler();
else if ("post" == context.Request.RequestType.ToLower())
handlerToReturn = new MyHttpHandler2();
return handlerToReturn;
}
public void ReleaseHandler(System.Web.IHttpHandler handler)
{
}
}
修改配置為
<httpHandlers>
<add verb="*" path="*.t1,*.t2" type="TestModule.HandlerFactory,TestModule"/>
</httpHandlers>
現在訪問尾碼名為.t1和.t2的url則會由httphandlerfactory來處理, 在GetHandler中決定哪個來處理這個請求.