asp.net ashx IHttpHandler c#
實(shí)際上,F(xiàn)ramework提供了一系列的接口和類,允許你對(duì)于Http請(qǐng)求進(jìn)行編程,而實(shí)現(xiàn)這一操作的一個(gè)主要的接口,就是 IHttpHandler(另一個(gè)是IHttpModule)。
應(yīng)該還記得第一節(jié)中我們提到過 ISAPI,它根據(jù)文件名后綴把不同的請(qǐng)求轉(zhuǎn)交給不同的處理程序。但是仔細(xì)看看就會(huì)發(fā)現(xiàn):幾乎一大半的文件都交給 aspnet_isapi.dll 去處理了。很明顯,aspnet_isapi.dll 不可能對(duì)每種文件采用同一種方式處理,那么 aspnet_isapi.dll 是如何更進(jìn)一步處理不同的文件,交由誰去處理呢?為了搞清楚這個(gè)問題,我們需要打開機(jī)器上C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\ 目錄下的web.config 文件。
NOTE:我查閱了很多資料,都說是在 machine.config 中,但實(shí)際上 v2.0.50727 下的machine.config中httpHandlers結(jié)點(diǎn)是這樣的:<httpHandlers />,并沒有給出詳細(xì)的處理程序,在Web.config中才能看到。而v1.1.4322 下的machine.config中卻有。
找到httpHandlers結(jié)點(diǎn),應(yīng)該可以看到如下這樣的代碼(做了省略):
<httpHandlers>
... ... //略
<add path="*.axd" verb="*" type="System.Web.HttpNotFoundHandler" validate="True" /><add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True" />
<add path="*.ascx" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" />
</httpHandlers>
可以看到,在<httpHandlers>結(jié)點(diǎn)中將不同的文件類型映射給不同的Handler去處理,對(duì)于.aspx來說,是由System.Web.UI.PageHandlerFactory來處理。而對(duì)于.cs來說,是由System.Web.HttpForbiddenHandler 處理,從ForbiddenHandler名字中出現(xiàn)的Forbidden (翻譯過來是“禁止”)可以看出,這個(gè)Handler可以避免我們的源碼被看到。
NOTE:System.Web.UI.PageHandlerFactory 是一個(gè)IHttpHandlerFactory,而不是一個(gè)單一的HttpHandler,IHttpHandlerFactory用來做什么后面會(huì)說明。
上面列出的是.Net Framework在處理Http請(qǐng)求時(shí)的所采用的默認(rèn)Handler。而如果我們要用編程的方式來操控一個(gè)Http請(qǐng)求,我們就需要實(shí)現(xiàn)IHttpHandler接口,來定制我們自己的需求。
IHttpHandler的定義是這樣的:
public interface IHttpHandler{
}
由上面可以看出IHttpHandler要求實(shí)現(xiàn)一個(gè)方法和一個(gè)屬性。其中 ProcessRequest,從名字(處理請(qǐng)求)看就知道這里應(yīng)該放置我們處理請(qǐng)求的主要代碼。
IsReusable屬性,MSDN上是這樣解釋的:獲取一個(gè)值,該值指示其他請(qǐng)求是否可以使用 IHttpHandler 實(shí)例。也就是說后繼的Http請(qǐng)求是不是可以繼續(xù)使用實(shí)現(xiàn)了該接口的類的實(shí)例,一般來說,我把它設(shè)置成true。
那么實(shí)現(xiàn)此接口的類形式應(yīng)該是這樣的:
public class CustomHandler : IHttpHandler{
}
而為了能使用這個(gè)自定義的HttpHandler,我們需要在應(yīng)用程序目錄下的Web.config中注冊(cè)它。
<system.web>
</system.web>
應(yīng)該發(fā)現(xiàn)這與之前在C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\目錄下web.config中看到的幾乎完全一樣。這里,path指的是請(qǐng)求的文件名稱,可以使用通配符擴(kuò)大范圍,也可以明確指定這個(gè)handler僅用于處理某個(gè)特定的文件(比如說:filename.aspx)的請(qǐng)求。verb指的是請(qǐng)求此文件的方式,可以是post或get,用*代表所有訪問方式。type屬性由“,”分隔成兩部分,第一部分是實(shí)現(xiàn)了接口的類名,第二部分是位于Bin目錄下的編譯過的程序集名稱。
NOTE:如果你新建一個(gè)項(xiàng)目,并且在項(xiàng)目下創(chuàng)建HandlerTest.cs,然后讓站點(diǎn)引用該項(xiàng)目,那么在生成解決方案的時(shí)候會(huì)自動(dòng)將編譯好的.dll文件添到Bin目錄中。
使用HttpHandler實(shí)現(xiàn)圖片防盜鏈
有了之前這么多的準(zhǔn)備知識(shí),實(shí)現(xiàn)現(xiàn)在的目標(biāo)就容易得多了:
NOTE:這個(gè)例子,以及下面的一個(gè)例子均來自于《Maximizing ASP.NET Real World, Object-Oriented Development》一書:
Step.1:創(chuàng)建文件 CustomHandler.cs,代碼如下:
using System;
using System.Web;
namespace CustomHandler{