天天看點

HttpHandler

  HttpHandler概述

  HttpHandler實際上是ISAPI擴充,負責處理http請求。HttpHandler是http請求的最底層,在該類中實作具體的請求響應。一個HttpHandler能且隻能處理一種類型的檔案或資源。

  IIS根據配置可以将很多檔案類型的請求都轉發給aspnet_isapi.dll,而aspnet_isapi則根據asp.net framework配置檔案中的檔案影射,将不同的檔案交給不同的處理程式。

  HttpHandler類是實作了接口IHttpHandler的具體類。IHttpHandler接口定義了如果要實作一個HTTP請求的處理所必需實作的一些系統約定,它包含兩個接口函數:

 public bool IsReusable

{

get { throw new NotImplementedException(); }

}

public void ProcessRequest(HttpContext context)

{

throw new NotImplementedException();

}

ProcessRequest:放置處理請求的實際代碼

IsReusabel: 以後的請求是否可重用該執行個體

  當一個HTTP請求經同HttpModule容器傳遞到HttpHandler容器中時,ASP.NET Framework會調用HttpHandler的PrecessRequest成員方法來對這個HTTP請求進行真正的處理。以一個ASPX頁面為例,正是在這裡一個ASPX頁面才被系統處了解析,并将處理完成的結果繼續經由HttpModule傳遞下去,直至到達用戶端。

HttpHandler注冊

asp.net有很多内置的HttpHandler,在web.config檔案中檢視<httphandlers/>節點:

 <httpHandlers>

... ... //略

<add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True" />

<add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" validate="True" />

<add path="*.asax" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />

<add path="*.ascx" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />

<add path="*.config" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />

<add path="*.cs" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />

<add path="*" verb="GET,HEAD,POST" type="System.Web.DefaultHttpHandler" validate="True" />

... ... //略

</httpHandlers>

要使HttpHandler可用,隻要在應用程式的web.config檔案中,按照以上方式進行相應的配置即可。

定制HttpHandler

 public class MyFirstHandler : IHttpHandler,IRequiresSessionState

{

#region IHttpHandler 成員

public bool IsReusable

{

get { return true; }

}

public void ProcessRequest(HttpContext context)

{

context.Response.Write("Hello HttpHandler");

context.Session["Test"] = "測試HttpHandler容器中調用Session";

context.Response.Write(context.Session["Test"]);

}

#endregion

}

  也可以直接生成.ashx檔案定義HttpHandler,方法是:Add New Item——〉Generic Handler,預設檔案代碼如下

 <%@ WebHandler Language="C#" Class="MyHandler" %>

using System;

using System.Web;

public class MyHandler : IHttpHandler {

public void ProcessRequest (HttpContext context) {

context.Response.ContentType = "text/plain;

context.Response.Write("Hello World");

}

public bool IsReusable {

get {

return false;

}

}

}

使用定制的HttpHandler

1  web.config配置

 <system.web>

<httpHandlers>

<add path="*.foo" verb="*" type="CustomHandlers.MyHandler,CustomHandlers" />

</httpHandlers>

</system.web>

2 設定ISAPI 

在IIS中設定ISAPI來進行檔案與處理程式映射:

  1. 打開IIS,選擇本範例所用的站點,右鍵,選擇“屬性”。
  2. 選擇“主目錄”頁籤,點選“配置...”按鈕。
  3. 點選“添加”,設定“可執行檔案”為“C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/aspnet_isapi.dll”,設定“擴充名”為“.foo”,點“确定”。
  4. 注意,不要勾選“檢查檔案是否存在”複選框,這樣不用建立檔案,隻要在位址欄輸入任意以.foo字尾結尾的檔案名,均會交由上面建立的Handler去處理,而不管這個檔案是否存在。

進行了這些設定以後,現在IIS就知道如何去處理對.foo字尾名檔案的請求了。

3 使用

1)直接從浏覽器上通路ashx頁面:http://localhost:2694/WebSite2/ModuleAndHandler/MyHandler.ashx

2)程式設計通路: <img src=MyHandler.ashx />,也可以給ashx檔案傳遞參數 <img src=MyHandler.ashx?id=12 />

3)在浏覽器上請求*.foo檔案:http://localhost:2694/WebSite2/ModuleAndHandler/a.foo

第1、2種請求方式需要建立ashx檔案,而第3種是cs類檔案

IHttpHandlerFactory

  如果我們有很多個HttpHandler分别映射不同字尾名的請求,這樣我們的Web.config會變得很冗長,或者,我們隻有在程式運作時才能确切地知道使用哪個Handler,這個時候,可以考慮實作 IHttpHandlerFactory來完成這一過程。

  實際上,ASP.NET Framework實際不直接将相關的頁面資源HTTP請求定位到一個其内部預設的IHttpHandler容器之上,而定位到了其内部預設的IHttpHandlerFactory上。IHttpHandlerFactory的作用是對IHttpHandler容器進行排程和管理。

  IHttpHandlerFactory接口包含兩個函數

public interface IHttpHandlerFactory{

    IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated);

    void ReleaseHandler(IHttpHandler handler);

}

可見,需要實作兩個方法,分别是 GetHandler() 和 ReleaseHandler()。

  • GetHandler(),傳回實作了IHttpHandler接口的類的執行個體。
  • ReleaseHandler(),使得Factory可以重複使用一個已經存在的Handler執行個體。  

  例如,要定義兩個Handler

class HandlerFactory:IHttpHandlerFactory{

public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated){

string path = context.Request.PhysicalPath;

if (Path.GetExtension(path) == ".rss"){

return new RSSHandler();

}

if (Path.GetExtension(path) == ".atom"){

return new ATOMHandler();

}

return null;

}

public void ReleaseHandler(IHttpHandler handler){

}

}

public class RSSHandler: IHttpHandler

{

public void ProcessRequest(HttpContext context)

{}

public bool IsReusable {

get { return true; }

}

}

public class ATOMHandler: IHttpHandler

{

public void ProcessRequest(HttpContext context)

{}

public bool IsReusable {

get { return true; }

}

}

這時,在Web.Config 中<system.web>節點下進行如下設定即可:

<httpHandlers>

<add path="*.rss,*.atom" type=" RssFeadsLib.HandlerFactory" verb="GET" />

</httpHandlers>

但是,這不能簡化IIS中ISAPI的設定,還是需要手動去對.rss和.atom分别設定。