重写IHttpHandler接口实现产生随机验证码图片

本文介绍如何创建自定义的HTTP处理程序以响应特定文件扩展名的请求,并展示了一个生成随机验证码图片的具体实例。

一、关于IHttpHandler接口

HTTP 处理程序介绍      

        ASP.NET HTTP 处理程序是响应对 ASP.NET Web 应用程序的请求而运行的过程(通常称为“终结点”)。最常用的处理程序是处理 .aspx 文件的 ASP.NET 页处理程序。用户请求 .aspx 文件时,页通过页处理程序来处理请求。

        ASP.NET 页处理程序仅仅是一种类型的处理程序。ASP.NET 还包括其他几种内置的处理程序,例如用于 .asmx 文件的 Web 服务处理程序。

        如果您需要进行特殊处理(可以在应用程序中使用文件扩展名进行标识),可以创建自定义 HTTP 处理程序。HTTP 处理程序可以访问应用程序上下文,包括请求用户的标识(如果已知)、应用程序状态和会话信息等。当请求 HTTP 处理程序时,ASP.NET 将调用相应处理程序上的 ProcessRequest 方法。处理程序的 ProcessRequest 方法创建一个响应,此响应随后发送回请求浏览器。就像任何页请求那样,响应将途经订阅了处理程序运行后所发生事件的所有 HTTP 模块。

        HTTP 处理程序可以是同步的也可以是异步的。同步处理程序在完成对为其调用该处理程序的 HTTP 请求的处理后才会返回。异步处理程序运行进程的行为与向用户发送响应无关。当您需要启动一个可能耗费很长时间的应用程序进程,而用户又无需等候进程完成以便从服务器获取响应时,异步处理程序非常有用。

创建自定义 HTTP 处理程序

        若要创建一个自定义 HTTP 处理程序,可以创建一个可实现 IHttpHandler 接口的类以创建同步处理程序,或者创建一个可实现 IHttpAsyncHandler 的类以创建异步处理程序。两种处理程序接口都要求您实现 IsReusable 属性和 ProcessRequest 方法。IsReusable 属性指定 IHttpHandlerFactory 对象(实际调用适当处理程序的对象)是否可以将您的处理程序放置在池中,并且重新使用它们以提高性能,或是否在每次需要处理程序时都必须创建新实例。ProcessRequest 方法负责实际处理单个 HTTP 请求。

创建文件扩展名

         创建一个类文件作为您的 HTTP 处理程序时,可以让您的处理程序响应尚未在 IIS 和 ASP.NET 中映射的任何文件扩展名。例如,如果您在创建用于生成 RSS 源的 HTTP 处理程序,则可以将处理程序映射到扩展名 .rss。为了让 ASP.NET 知道哪个处理程序将用于您的自定义文件扩展名,必须在 IIS 中将处理程序类文件的扩展名映射到 ASP.NET,并且在您的应用程序中将该扩展名映射到您的自定义处理程序。

        默认情况下,ASP.NET 为自定义 HTTP 处理程序映射文件扩展名 .ashx 的方式与将扩展名 .aspx 映射到 ASP.NET 页处理程序的方式相同。因此,如果您创建具有文件扩展名 .ashx 的 HTTP 处理程序类,该处理程序将自动注册到 IIS 和 ASP.NET。

        如果想要为您的处理程序创建自定义文件扩展名,则必须显式将该扩展名注册到 IIS 和 ASP.NET。不使用文件扩展名 .ashx 的好处是您的处理程序随后可以重新用于其他扩展名映射。例如,在某个应用程序中,您的自定义处理程序可能响应以 .rss 结尾的请求,而在另一个应用程序中,您的自定义处理程序可能响应以 .feed 结尾的请求。再举一例,您的处理程序可能映射到同一应用程序中的两个文件扩展名,但可能基于扩展名创建两个不同的响应。

二、产生随机数及图片文件类(保存为CaptchaImage.cs)

 

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;

/// <summary>
/// 产生随机验证图片。
/// 代码来自CNBlogsDottext10Beta2。
/// http://scottwater.com/
/// http://www.cnblogs.com/
/// </summary>

public class CaptchaImage : IDisposable
{
    
// Public properties (all read-only).
    public string Text
    
{
        
get return this.text; }
    }

    
public Bitmap Image
    
{
        
get return this.image; }
    }

    
public int Width
    
{
        
get return this.width; }
    }

    
public int Height
    
{
        
get return this.height; }
    }


    
// Internal properties.
    private string text;
    
private int width;
    
private int height;
    
private string familyName = "黑体";
    
private Bitmap image;

    
// For generating random numbers.
    private Random random = new Random();

    
// ====================================================================
    
// Initializes a new instance of the CaptchaImage class using the
    
// specified text, width and height.
    
// ====================================================================
    public CaptchaImage(string s, int width, int height)
    
{
        
this.text = s;
        
this.SetDimensions(width, height);
        
this.GenerateImage();
    }


    
// ====================================================================
    
// Initializes a new instance of the CaptchaImage class using the
    
// specified text, width, height and font family.
    
// ====================================================================
    public CaptchaImage(string s, int width, int height, string familyName)
    
{
        
this.text = s;
        
this.SetDimensions(width, height);
        
this.SetFamilyName(familyName);
        
this.GenerateImage();
    }


    
// ====================================================================
    
// This member overrides Object.Finalize.
    
// ====================================================================
    ~CaptchaImage()
    
{
        Dispose(
false);
    }


    
// ====================================================================
    
// Releases all resources used by this object.
    
// ====================================================================
    public void Dispose()
    
{
        GC.SuppressFinalize(
this);
        
this.Dispose(true);
    }


    
// ====================================================================
    
// Custom Dispose method to clean up unmanaged resources.
    
// ====================================================================
    protected virtual void Dispose(bool disposing)
    
{
        
if(disposing)
            
// Dispose of the bitmap.
            this.image.Dispose();
    }


    
// ====================================================================
    
// Sets the image width and height.
    
// ====================================================================
    private void SetDimensions(int width, int height)
    
{
        
// Check the width and height.
        if(width <= 0)
            
throw new ArgumentOutOfRangeException("width", width, "Argument out of range, must be greater than zero.");
        
if(height <= 0)
            
throw new ArgumentOutOfRangeException("height", height, "Argument out of range, must be greater than zero.");
        
this.width = width;
        
this.height = height;
    }


    
// ====================================================================
    
// Sets the font used for the image text.
    
// ====================================================================
    private void SetFamilyName(string familyName)
    
{
        
// If the named font is not installed, default to a system font.
        try
        
{
            Font font 
= new Font(this.familyName, 12F);
            
this.familyName = familyName;
            font.Dispose();
        }

        
catch
        
{
            
this.familyName = System.Drawing.FontFamily.GenericSerif.Name;
        }

    }


    
// ====================================================================
    
// Creates the bitmap image.
    
// ====================================================================
    private void GenerateImage()
    
{
        
// Create a new 32-bit bitmap image.
        Bitmap bitmap = new Bitmap(this.width, this.height, PixelFormat.Format32bppArgb);

        
// Create a graphics object for drawing.
        Graphics g = Graphics.FromImage(bitmap);
        g.SmoothingMode 
= SmoothingMode.AntiAlias;
        Rectangle rect 
= new Rectangle(00this.width, this.height);

        
// Fill in the background.
        HatchBrush hatchBrush = new HatchBrush(HatchStyle.SmallConfetti, Color.LightGray, Color.White);
        g.FillRectangle(hatchBrush, rect);

        
// Set up the text font.
        SizeF size;
        
float fontSize = rect.Height + 1;
        Font font;
        
// Adjust the font size until the text fits within the image.
        do
        
{
            fontSize
--;
            font 
= new Font(this.familyName, fontSize, FontStyle.Bold);
            size 
= g.MeasureString(this.text, font);
        }
 while(size.Width > rect.Width);

        
// Set up the text format.
        StringFormat format = new StringFormat();
        format.Alignment 
= StringAlignment.Center;
        format.LineAlignment 
= StringAlignment.Center;

        
// Create a path using the text and warp it randomly.
        GraphicsPath path = new GraphicsPath();
        path.AddString(
this.text, font.FontFamily, (int)font.Style, font.Size, rect, format);
        
float v = 4F;
        PointF[] points 
=
            
{
                
new PointF(this.random.Next(rect.Width) / v, this.random.Next(rect.Height) / v),
                
new PointF(rect.Width - this.random.Next(rect.Width) / v, this.random.Next(rect.Height) / v),
                
new PointF(this.random.Next(rect.Width) / v, rect.Height - this.random.Next(rect.Height) / v),
                
new PointF(rect.Width - this.random.Next(rect.Width) / v, rect.Height - this.random.Next(rect.Height) / v)
            }
;
        Matrix matrix 
= new Matrix();
        matrix.Translate(0F, 0F);
        path.Warp(points, rect, matrix, WarpMode.Perspective, 0F);

        
// Draw the text.
        hatchBrush = new HatchBrush(HatchStyle.LargeConfetti, Color.DarkGray, Color.DarkGray);
        g.FillPath(hatchBrush, path);

        
// Add some random noise.
        int m = Math.Max(rect.Width, rect.Height);
        
for(int i = 0; i < (int)(rect.Width * rect.Height / 30F); i++)
        
{
            
int x = this.random.Next(rect.Width);
            
int y = this.random.Next(rect.Height);
            
int w = this.random.Next(m / 50);
            
int h = this.random.Next(m / 50);
            g.FillEllipse(hatchBrush, x, y, w, h);
        }


        
// Clean up.
        font.Dispose();
        hatchBrush.Dispose();
        g.Dispose();

        
// Set the image.
        this.image = bitmap;
    }


    
public static string GenerateRandomCode()
    
{
        
string s = "";
        Random random 
= new Random();
        
for(int i = 0; i < 4; i++)
            s 
= String.Concat(s, random.Next(10).ToString());
        
return s;
    }

}

三、ValidImage1 类重写IHttpHandler接口,向页面输出img文件流(保存为ValidImage1.ashx)

 

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

using System;
using System.Web;
using System.Drawing.Imaging;


public class ValidImage1 : IHttpHandler
{


    
public void ProcessRequest(HttpContext context)
    
{
       
            context.Response.ContentType 
= "image/jpeg";
            
string str = context.Request.Cookies["Suijiyanzhengma"].Value;
            
using (CaptchaImage ci = new CaptchaImage(str, 15640))
            
{
                ci.Image.Save(context.Response.OutputStream, ImageFormat.Jpeg);
            }

     

    }

 
    
public bool IsReusable
    
{
        
get
        
{
            
return false;
        }

    }

}

四、页面调用ValidImage1.ashx

Default2.aspx

 

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    
<title>无标题页</title>
</head>
<body>
    
<form id="form1" runat="server">
    
<div>
        产生随机数Demo:
<br />
        
<br />
    
<img src="ValidImage1.ashx" />
    
</div>
    
</form>
</body>
</html>

Default2.aspx.cs

 

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Specialized;
using System.Text.RegularExpressions;



public partial class Default2 : System.Web.UI.Page
{
    
protected void Page_Load(object sender, EventArgs e)
    
{
        Response.Cookies[
"Suijiyanzhengma"].Value = CaptchaImage.GenerateRandomCode();
               
    }




}

           注意:调用过程的传值用了一个cookies

五、效果

本 PPT 介绍了制药厂房中供配电系统的总体概念与设计要点,内容包括: 洁净厂房的特点及其对供配电系统的特殊要求; 供配电设计的一般原则与依据的国家/行业标准; 从上级电网到工厂变电所、终端配电的总体结构与模块化设计思路; 供配电范围:动力配电、照明、通讯、接地、防雷与消防等; 动力配电中电压等级、接地系统形式(如 TN-S)、负荷等级与可靠性、UPS 配置等; 照明的电源方式、光源选择、安装方式、应急与备用照明要求; 通讯系统、监控系统在生产管理与消防中的作用; 接地与等电位连接、防雷等级与防雷措施; 消防设施及其专用供电(消防泵、排烟风机、消防控制室、应急照明等); 常见高压柜、动力柜、照明箱等配电设备案例及部分设计图纸示意; 公司已完成的典型项目案例。 1. 工程背景与总体框架 所属领域:制药厂房工程的公用工程系统,其中本 PPT 聚焦于供配电系统。 放在整个公用工程中的位置:与给排水、纯化水/注射用水、气体与热力、暖通空调、自动化控制等系统并列。 2. Part 01 供配电概述 2.1 洁净厂房的特点 空间密闭,结构复杂、走向曲折; 单相设备、仪器种类多,工艺设备昂贵、精密; 装修材料与工艺材料种类多,对尘埃、静电等更敏感。 这些特点决定了:供配电系统要安全可靠、减少积尘、便于清洁和维护。 2.2 供配电总则 供配电设计应满足: 可靠、经济、适用; 保障人身与财产安全; 便于安装与维护; 采用技术先进的设备与方案。 2.3 设计依据与规范 引用了大量俄语标准(ГОСТ、СНиП、SanPiN 等)以及国家、行业和地方规范,作为设计的法规基础文件,包括: 电气设备、接线、接地、电气安全; 建筑物电气装置、照明标准; 卫生与安全相关规范等。 3. Part 02 供配电总览 从电源系统整体结构进行总览: 上级:地方电网; 工厂变电所(10kV 配电装置、变压
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值