經過前兩篇[ASP.NET基礎之HttpModule學習]和[ASP.NET基礎之HttpContext學習]文章的學習我們對ASP.NET的基礎內容有一個比較詳細的了解,本文將對第三個比較重要的知識HttpHandler進行學習,將通過一些理論跟實例來演示HttpHandler運用;有部分理論知識來源於網源,希望對您的閱讀有所幫助;
一:HttpHandler理論知識
1:IHttpHandler定義了如果要實現一個HTTP請求的處理所必需實現的一些系統約定。HttpHandler與HttpModule不同,一旦定義了自己的HttpHandler類,那么它對系統的HttpHandler的關系將是“覆蓋”關系。
2:當一個HTTP請求經同HttpModule容器傳遞到HttpHandler容器中時,ASP.NET Framework會調用HttpHandler的ProcessRequest成員方法來對這個HTTP請求進行真正的處理。以一個ASPX頁面為例,正是在這里一個ASPX頁面才被系統處理解析,並將處理完成的結果繼續經由HttpModule傳遞下去,直至到達客戶端。對於ASPX頁面,ASP.NET Framework在默認情況下是交給System.Web.UI.PageHandlerFactory這個HttpHandlerFactory來處理的。HttpHandlerFactory;HttpHandlerFactory,是指當一個HTTP請求到達這個HttpHandler Factory時,HttpHandlerFactory會提供出一個HttpHandler容器,交由這個HttpHandler容器來處理這個HTTP請求。針對.aspx在machine.config中是這樣定義的:
<add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory"/>
3:一個HTTP請求都是最終交給一個HttpHandler容器中的ProcessRequest方法來處理的。
4:其實我們可以自定義HttpHandler來處理某些特殊文件的請求或者邏輯的實現;自定義HttpHandler必須實現接口IHttpHandler;其中屬性IsReusable表示獲取一個值,該值指示其他請求是否可以使用 IHttpHandler 實例。而方法ProcessRequest則是以一個HttpContext的上下文為參數;這些我們就可以操作HttpContext里封裝的Request,Response,Server等;
二:HttpHandler之一般程序處理類(Handler.ashx)
1:在我們講解自定義HttpHandler時,我們首先看下VS里的一般程序處理類(Handler.ashx),在我們平常開發過程中其實已經有應用到一些HttpHandler,比如我們新建一個一般程序處理類時
<%@ WebHandler Language="C#" Class="Handler" %> using System; using System.Web; public class Handler : IHttpHandler { public void ProcessRequest (HttpContext context) { context.Response.ContentType = "text/plain"; context.Response.Write("Hello World"); } public bool IsReusable { get { return false; } } }
上面的代碼是增加完一個一般處理程序系統默認為我們增加的內容;以前對HttpHandler不了解,所以也不是很了解為什么會自動增加這樣的代碼;其實它是實現的IHttpHandler接口,對接口成員的一個實現;
2:若是使用到一般處理程序時有個地方要注意,就是它對Session值的讀起時;運用上面的Handler.ashx是讀不到Session值;實例如下:
我們定義一個NotSessionHandler.ashx用來讀取Session的值:
<%@ WebHandler Language="C#" Class="NotSessionHandler" %> using System; using System.Web; public class NotSessionHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { Object SessionValue = context.Session["NotSession"]; string Result = string.Empty; if (SessionValue != null) { Result = SessionValue.ToString(); } else { Result = "沒有實現接口;Session的值無法讀到"; } context.Response.ContentType = "text/plain"; context.Response.Write(Result); } public bool IsReusable { get { return false; } } }
首先我們再Default.aspx頁面進行寫入Session值,並讓NotSessionHandler.ashx顯示:
protected void Button4_Click(object sender, EventArgs e) { Session["NotSession"] = "踏浪帥"; Response.Redirect("NotSessionHandler.ashx"); }
運行結果如下(從下面不然發現讀取失敗):
為什么NotSessionHandler.ashx讀取不到Session 的值?它不是已經有當前HttpContext上下文?其實NotSessionHandler.ashx還必須實現Session的一個重要接口IRequiresSessionState;其實接口IRequiresSessionState里並沒有什么內容,只是一個簡單的標識而已;它是存在於System.Web.SessionState內
接着我們實現對上面的NotSessionHandler.ashx進行修改,讓它實現接口IRequiresSessionState;
using System; using System.Web; using System.Web.SessionState; public class NotSessionHandler : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { Object SessionValue = context.Session["NotSession"]; string Result = string.Empty; if (SessionValue != null) { Result = SessionValue.ToString(); } else { Result = "沒有實現接口;Session的值無法讀到"; } context.Response.ContentType = "text/plain"; context.Response.Write(Result); } public bool IsReusable { get { return false; } } }
運行結果:
三:自定義HttpHandler
1:自定義一個HttpHandler處理程序只要兩步就可以實現了,第一是讓類實現接口IHttpHandler,第二就是增加Web.config配置文件;
2:接下來我們將通過一個實例來演示對我們自個建的后綴類型進行訪問;
步驟一:我們先建一個類MyHttpHandler類並實現接口IHttpHandler,此處只是顯示內容;
using System.Web; using System.IO; using System.Text; public class MyHttpHandler:IHttpHandler { public MyHttpHandler() { } public bool IsReusable { get { return true; } } public void ProcessRequest(HttpContext context) { HttpRequest request = context.Request; HttpResponse response = context.Response; response.Write("這個是自定義的HttpHandler </br>"); response.Write("訪問URL地址:" + request.Url.Segments[2]+"</br>"); string FileStr = request.PhysicalPath; if (File.Exists(FileStr)) { response.Write("以下是文件Cnblogs.wujy的內容 <br/>"); FileInfo fileInfo = new FileInfo(FileStr); StreamReader reader = new StreamReader(FileStr, Encoding.Default); string StrLine = string.Empty; while (!string.IsNullOrEmpty(StrLine = reader.ReadLine())) { response.Write(StrLine + "</br>"); } reader.Close(); } else { response.Write("文件不存在"); } } }
步驟二:在站點里我們新建一個Cnblogs.wujy的文件,此處的后綴名為:wujy 它是我自定義的一個后綴;Cnblogs.wujy文件內容:踏浪帥的地址www.cnblogs.com/wujy
步驟三:修改web.config配置;
<httpHandlers> <add path="*.wujy" verb="*" type="MyHttpHandler"/> </httpHandlers>
運行效果如下(如果部署在IIS上可能要對后綴進行映射,在IIS里進行設置,不然這種可能在IIS那就直接訪問不了):
上面我們是直接在VS運行時的情況,當我們部署在IIS要進行設置,不然在IIS里訪問Cnblogs.wujy就會報下面的錯誤:
由於我本地的IIS為版7.0所以設置如下(若是IIS5或II6可以在應用程序擴展映射增加后綴):
3:接下來我們將通過一個實例,此實例是在ASP.Net夜話里看到的;實例主要實現一個對站點里的圖片進行打水印的功能,這個功能是圖片上傳后在訪問圖片時打水印,它其實並不有把水印打在圖片上只是訪問時才顯示出水印,保持圖片的原來模樣;
步驟一:我們新建一個實現接口IHttpHandler的類WaterMarkHandler:
using System; using System.Web; using System.Drawing; using System.Drawing.Imaging; using System.IO; /// <summary> /// 動態給圖片添加水印的類 /// </summary> public class WaterMarkHandler:IHttpHandler { public WaterMarkHandler() { } #region IHttpHandler 成員 /// <summary> /// 指示其它請求是否可以使用這個實例,如果是true,則放入池中接受其它請求以提高請求 /// </summary> public bool IsReusable { get { return true; } } /// <summary> /// 處理請求 /// </summary> /// <param name="context">當前HTTP請求的上下文</param> public void ProcessRequest(HttpContext context) { //獲取請求的物理圖片路徑 string imagePath = context.Request.PhysicalPath; Image image = null; if (File.Exists(imagePath)) { //定義水印文字 string text = "給圖片增加水印[踏浪帥]"; //定義水印文字字體大小 int fontSize = 12; //水印文字字體 Font font = new Font("宋體", fontSize); //根據圖片物理地址加載圖片 image = Image.FromFile(imagePath); Graphics g = Graphics.FromImage(image); //獲取要繪制水印文字所需要的顯示區域大小 SizeF size=g.MeasureString(text, font); if (size.Width > image.Width || size.Height > image.Height) { //如果要顯示的圖片的尺寸都不足以顯示按照指定字體來添加水印 //可以減小字體大小或者不添加水印(太小了沒辦法添加嘛) } else//添加水印文字 { Brush brush = Brushes.Red; //在圖片上添加水印,繪制水印文字在圖片的右下角 g.DrawString(text, font, brush, image.Width - size.Width, image.Height - size.Height); g.Dispose(); } } else//如果不存在,指定一個默認圖片進行顯示 { imagePath = context.Server.MapPath("~/images/nopic.jpg"); image = Image.FromFile(imagePath); } image.Save(context.Response.OutputStream, ImageFormat.Jpeg);//將添加水印的圖片輸入到當前流中 } #endregion }
步驟二:修改配置文件web.config(說明針對本站的圖片都用上面的處理程序類處理)
<httpHandlers> <add path="*.jpg" verb="*" type="WaterMarkHandler"/> </httpHandlers>
步驟三:我們新建一個頁面用來顯示圖片:
<html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <img src="Image/1.jpg" alt="打水印"/> </div> </form> </body> </html>
運行查看效果圖:
其實我們還有很多在平時開發中可能會用到自定義HttpHandler的功能,比如我們最常用的驗證碼功能和網站的圖片防盜連功能等;
如果,您認為閱讀這篇博客讓您有些收獲,不妨點擊一下右下角的【推薦】按鈕。 因為,我的寫作熱情也離不開您的肯定支持。
感謝您的閱讀 [源代碼下載]
最近有個妹子弄的一個關於擴大眼界跟內含的訂閱號,每天都會更新一些深度內容,在這里如果你感興趣也可以關注一下(嘿對美女跟知識感興趣),當然可以關注后輸入:github 會有我的微信號,如果有問題你也可以在那找到我;當然不感興趣無視此信息;