ASP.NET基礎之HttpHandler學習

通過前兩篇[ASP.NET基礎之HttpModule學習]和[ASP.NET基礎之HttpContext學習]文章的學習咱們對ASP.NET的基礎內容有一個比較詳細的瞭解,本文將對第三個比較重要的知識HttpHandler進行學習,將經過一些理論跟實例來演示HttpHandler運用;有部分理論知識來源於網源,但願對您的閱讀有所幫助;html

一:HttpHandler理論知識git

1:IHttpHandler定義了若是要實現一個HTTP請求的處理所必需實現的一些系統約定。HttpHandler與HttpModule不一樣,一旦定義了本身的HttpHandler類,那麼它對系統的HttpHandler的關係將是「覆蓋」關係。github

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中是這樣定義的:web

<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接口,對接口成員的一個實現;ui

2:如果使用到通常處理程序時有個地方要注意,就是它對Session值的讀起時;運用上面的Handler.ashx是讀不到Session值;實例以下:spa

咱們定義一個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 會有個人微信號,若是有問題你也能夠在那找到我;固然不感興趣無視此信息;

相關文章
相關標籤/搜索