看过网上很多关于ASP.NET生成 验证码的东西。大部分都牺牲了一个aspx页面来生成验证码图片。 而且还不利于二次使用。 于是想一直琢磨着想写一个不用牺牲一个aspx页面来完成验证码的控件,在使用的时候只需要引用一个dll并且在工具箱中直接拖到页面上就可。 经过几天努力还真琢磨出来了一个个人认为比较好的方法,于是拿出来共享一下,希望和大家交流交流意见。
现在开始
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Drawing;
using System.IO;
using System.Web.SessionState;
namespace jdTools.Web
{
public class VerifyImageHttpHandle : IHttpHandler, IRequiresSessionState
{
private string GetRandomNumberString(int codeCount)
{
int j1;
string strChoice = "2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,T,U,V,W,X,Y,Z";
string[] strResult = strChoice.Split(new Char[] { ',' });
string strReturn = "";
Random rnd = new Random(unchecked((int)DateTime.Now.Ticks));
for (int i = 0; i < codeCount; i++)
{
Random rnd1 = new Random(rnd.Next() * unchecked((int)DateTime.Now.Ticks));
j1 = rnd1.Next(strResult.Length);
rnd = new Random(rnd.Next() * unchecked((int)DateTime.Now.Ticks));
strReturn = strReturn + strResult[j1].ToString();
}
return strReturn;
}
private Color GetColor()
{
return Color.Black;
}
private Bitmap CreateImage(string str_ValidateCode)
{
Random newRandom = new Random((int)DateTime.Now.Ticks);
int int_ImageWidth = str_ValidateCode.Length * 14;
int int_ImageHeight = 20;
// 图高20px
Bitmap theBitmap = new Bitmap(int_ImageWidth, int_ImageHeight);
Graphics theGraphics = Graphics.FromImage(theBitmap);
// 白色背景
theGraphics.Clear(Color.White);
// 灰色边框
theGraphics.DrawRectangle(new Pen(Color.LightGray, 1), 0, 0, int_ImageWidth – 1, int_ImageHeight);
int num = theBitmap.Width * theBitmap.Height * 30 / 100;
for (int iCount = 0; iCount < num; iCount++)
{
// 在随机的位置使用随机的颜色设置图片的像素
int x = newRandom.Next(theBitmap.Width);
int y = newRandom.Next(theBitmap.Height);
int r = newRandom.Next(255);
int g = newRandom.Next(255);
int b = newRandom.Next(255);
Color c = Color.FromArgb(r, g, b);
theBitmap.SetPixel(x, y, c);
}//for
// 10pt的字体
Font theFont = new Font("Arial", 12, FontStyle.Bold);
for (int int_index = 0; int_index < str_ValidateCode.Length; int_index++)
{
string str_char = str_ValidateCode.Substring(int_index, 1);
Brush newBrush = new SolidBrush(GetColor());
Point thePos = new Point(int_index * 13 + 1 + newRandom.Next(3), 1 + newRandom.Next(3));
theGraphics.DrawString(str_char, theFont, newBrush, thePos);
}
theGraphics.Dispose();
return theBitmap;
}
#region IHttpHandler 成员
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
HttpResponse Response = context.Response;
// 将生成的图片发回客户端
MemoryStream ms = new MemoryStream();
string NumStr=GetRandomNumberString(5);
context.Session.Add("Verify", NumStr);
Bitmap theBitmap = CreateImage(NumStr);
theBitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
Response.ClearContent(); //需要输出图象信息 要修改HTTP头
Response.ContentType = "image/jpeg";
Response.BinaryWrite(ms.ToArray());
theBitmap.Dispose();
ms.Close();
ms.Dispose();
Response.End();
}
#endregion
}
}
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Drawing;
using System.IO;
using System.Web.SessionState;
namespace jdTools.Web
{
public class VerifyImageHttpHandle : IHttpHandler, IRequiresSessionState
{
private string GetRandomNumberString(int codeCount)
{
int j1;
string strChoice = "2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,T,U,V,W,X,Y,Z";
string[] strResult = strChoice.Split(new Char[] { ',' });
string strReturn = "";
Random rnd = new Random(unchecked((int)DateTime.Now.Ticks));
for (int i = 0; i < codeCount; i++)
{
Random rnd1 = new Random(rnd.Next() * unchecked((int)DateTime.Now.Ticks));
j1 = rnd1.Next(strResult.Length);
rnd = new Random(rnd.Next() * unchecked((int)DateTime.Now.Ticks));
strReturn = strReturn + strResult[j1].ToString();
}
return strReturn;
}
private Color GetColor()
{
return Color.Black;
}
private Bitmap CreateImage(string str_ValidateCode)
{
Random newRandom = new Random((int)DateTime.Now.Ticks);
int int_ImageWidth = str_ValidateCode.Length * 14;
int int_ImageHeight = 20;
// 图高20px
Bitmap theBitmap = new Bitmap(int_ImageWidth, int_ImageHeight);
Graphics theGraphics = Graphics.FromImage(theBitmap);
// 白色背景
theGraphics.Clear(Color.White);
// 灰色边框
theGraphics.DrawRectangle(new Pen(Color.LightGray, 1), 0, 0, int_ImageWidth – 1, int_ImageHeight);
int num = theBitmap.Width * theBitmap.Height * 30 / 100;
for (int iCount = 0; iCount < num; iCount++)
{
// 在随机的位置使用随机的颜色设置图片的像素
int x = newRandom.Next(theBitmap.Width);
int y = newRandom.Next(theBitmap.Height);
int r = newRandom.Next(255);
int g = newRandom.Next(255);
int b = newRandom.Next(255);
Color c = Color.FromArgb(r, g, b);
theBitmap.SetPixel(x, y, c);
}//for
// 10pt的字体
Font theFont = new Font("Arial", 12, FontStyle.Bold);
for (int int_index = 0; int_index < str_ValidateCode.Length; int_index++)
{
string str_char = str_ValidateCode.Substring(int_index, 1);
Brush newBrush = new SolidBrush(GetColor());
Point thePos = new Point(int_index * 13 + 1 + newRandom.Next(3), 1 + newRandom.Next(3));
theGraphics.DrawString(str_char, theFont, newBrush, thePos);
}
theGraphics.Dispose();
return theBitmap;
}
#region IHttpHandler 成员
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
HttpResponse Response = context.Response;
// 将生成的图片发回客户端
MemoryStream ms = new MemoryStream();
string NumStr=GetRandomNumberString(5);
context.Session.Add("Verify", NumStr);
Bitmap theBitmap = CreateImage(NumStr);
theBitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
Response.ClearContent(); //需要输出图象信息 要修改HTTP头
Response.ContentType = "image/jpeg";
Response.BinaryWrite(ms.ToArray());
theBitmap.Dispose();
ms.Close();
ms.Dispose();
Response.End();
}
#endregion
}
}
GetRandomNumberString方法用于生成指定个数的随机数字符串。
IHttpHandle接口的ProcessRequest方法可以启用 HTTP Web 请求的处理。
类VerifyImageHttpHandle 继承了IHttpHandle接口用于自定义程序处理的Web请求。然后在web.config的<system.web>节中配置
<httpHandlers>
<add verb="*" path="VerifyImg.jd" type="jdTools.Web.VerifyImageHttpHandle"/>
</httpHandlers>
<add verb="*" path="VerifyImg.jd" type="jdTools.Web.VerifyImageHttpHandle"/>
</httpHandlers>
此时在浏览器中访问VerifyImg.jd时就会得到一个验证码图片,生成验证码的内容就完成了。
现在我们要自定义一个WEB自定义控件。其代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace jdTools.Web.UI
{
[ToolboxData("<{0}:VerifyImage runat=server></{0}:VerifyImage>")]
public class VerifyImage : WebControl
{
public string Value
{
get { return HttpContext.Current.Session["Verify"].ToString(); }
}
public virtual ImageAlign ImageAlign
{
get
{
object obj2 = this.ViewState["ImageAlign"];
if (obj2 != null)
{
return (ImageAlign)obj2;
}
return ImageAlign.NotSet;
}
set
{
if ((value < ImageAlign.NotSet) || (value > ImageAlign.TextTop))
{
throw new ArgumentOutOfRangeException("value");
}
this.ViewState["ImageAlign"] = value;
}
}
public VerifyImage()
: base(HtmlTextWriterTag.Img)
{ }
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
writer.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "pointer");
writer.AddAttribute("onclick", "this.src='VerifyImg.jd?id='+Math.random()", true);
writer.AddAttribute(HtmlTextWriterAttribute.Src, "VerifyImg.jd");
string str2;
switch (this.ImageAlign)
{
case ImageAlign.Left:
str2 = "left";
break;
case ImageAlign.Right:
str2 = "right";
break;
case ImageAlign.Baseline:
str2 = "baseline";
break;
case ImageAlign.Top:
str2 = "top";
break;
case ImageAlign.Middle:
str2 = "middle";
break;
case ImageAlign.Bottom:
str2 = "bottom";
break;
case ImageAlign.AbsBottom:
str2 = "absbottom";
break;
case ImageAlign.AbsMiddle:
str2 = "absmiddle";
break;
case ImageAlign.NotSet:
str2="";
break;
default:
str2 = "texttop";
break;
}
if (str2 != "")
writer.AddAttribute(HtmlTextWriterAttribute.Align, str2);
}
}
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace jdTools.Web.UI
{
[ToolboxData("<{0}:VerifyImage runat=server></{0}:VerifyImage>")]
public class VerifyImage : WebControl
{
public string Value
{
get { return HttpContext.Current.Session["Verify"].ToString(); }
}
public virtual ImageAlign ImageAlign
{
get
{
object obj2 = this.ViewState["ImageAlign"];
if (obj2 != null)
{
return (ImageAlign)obj2;
}
return ImageAlign.NotSet;
}
set
{
if ((value < ImageAlign.NotSet) || (value > ImageAlign.TextTop))
{
throw new ArgumentOutOfRangeException("value");
}
this.ViewState["ImageAlign"] = value;
}
}
public VerifyImage()
: base(HtmlTextWriterTag.Img)
{ }
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
writer.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "pointer");
writer.AddAttribute("onclick", "this.src='VerifyImg.jd?id='+Math.random()", true);
writer.AddAttribute(HtmlTextWriterAttribute.Src, "VerifyImg.jd");
string str2;
switch (this.ImageAlign)
{
case ImageAlign.Left:
str2 = "left";
break;
case ImageAlign.Right:
str2 = "right";
break;
case ImageAlign.Baseline:
str2 = "baseline";
break;
case ImageAlign.Top:
str2 = "top";
break;
case ImageAlign.Middle:
str2 = "middle";
break;
case ImageAlign.Bottom:
str2 = "bottom";
break;
case ImageAlign.AbsBottom:
str2 = "absbottom";
break;
case ImageAlign.AbsMiddle:
str2 = "absmiddle";
break;
case ImageAlign.NotSet:
str2="";
break;
default:
str2 = "texttop";
break;
}
if (str2 != "")
writer.AddAttribute(HtmlTextWriterAttribute.Align, str2);
}
}
}
VerifyImage 类定义了两个属性。其中Value属性用于取得session中存放的验证码的值。
这里就很简单了,没有必要详说。
在使用的时候aspx页面如下:
<ul>
<li>用户名:<asp:TextBox ID="txtUserName" runat="server"></asp:TextBox></li>
<li>密 码:<asp:TextBox ID="txtPassWord" runat="server"></asp:TextBox></li>
<li>检证码:<asp:TextBox ID="txtVerify" runat="server" Width="50px"></asp:TextBox><jd:VerifyImage ID="verify" runat="server" Height="23px" ImageAlign="AbsMiddle"/></li>
</ul>
<li>用户名:<asp:TextBox ID="txtUserName" runat="server"></asp:TextBox></li>
<li>密 码:<asp:TextBox ID="txtPassWord" runat="server"></asp:TextBox></li>
<li>检证码:<asp:TextBox ID="txtVerify" runat="server" Width="50px"></asp:TextBox><jd:VerifyImage ID="verify" runat="server" Height="23px" ImageAlign="AbsMiddle"/></li>
</ul>
aspx.cs中:
if (txtVerify.Text != verify.Value)
{
//.验证码错误
}
else
{
//验证码正确
}
{
//.验证码错误
}
else
{
//验证码正确
}