共享一款ASP.NET验证码控件(附详细用法)
最近在完善我的毕业设计——ASP.NET(C#)实现的三层构架的二手交易系统,觉得有必要加上验证码,这样网站的安全性会提升一些。于是利用百度、谷歌反复搜索,终于到了一款比较牛叉的验证码控件。原作者不详,这里附上一个地址>>>。程序我做了一些小小的修改。
按原文所说的操作,根本编译不了。原文的用法可以查看上面的链接地址,这里我贴出我自己的用法。我将两个类整合到一个.cs文件中了(这里命名为AuthCode.cs),程序如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Web.SessionState;
using System.Drawing;
using System.IO;
namespace AuthCode
{
[ToolboxData("<{0}:AuthCode runat=server></{0}:AuthCode>")]
public class AuthCode : WebControl
{
/// 〈summary>
/// 获得验证码的值
/// 〈/summary>
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Web.SessionState;
using System.Drawing;
using System.IO;
namespace AuthCode
{
[ToolboxData("<{0}:AuthCode runat=server></{0}:AuthCode>")]
public class AuthCode : WebControl
{
/// 〈summary>
/// 获得验证码的值
/// 〈/summary>
/// 〈returns>验证码〈/returns>
public string GetValue()
{
return HttpContext.Current.Session["value"].ToString();
}
[Bindable(true)]
[Category("Appearance")]
[Description("验证码字符长度")]
[DefaultValue("ss")]
[Localizable(true)]
//长度
internal static int mySize;
public int MySize
public string GetValue()
{
return HttpContext.Current.Session["value"].ToString();
}
[Bindable(true)]
[Category("Appearance")]
[Description("验证码字符长度")]
[DefaultValue("ss")]
[Localizable(true)]
//长度
internal static int mySize;
public int MySize
{
get { return Size; }
set
{
Size = value;
}
}
public AuthCode()
asp 字符串转数组 : base(HtmlTextWriterTag.Img)//重写父类的构造(输出流的HTML标记)
{ }
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);//将要输出的的HTML标签的属性和样式添加到
get { return Size; }
set
{
Size = value;
}
}
public AuthCode()
asp 字符串转数组 : base(HtmlTextWriterTag.Img)//重写父类的构造(输出流的HTML标记)
{ }
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);//将要输出的的HTML标签的属性和样式添加到
指定的 HtmlTextWriter中
writer.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "pointer");//添加样式
writer.AddAttribute("onclick", "this.src='img.jd?id='+Math.random()");//添加js VerifyImg.jd
writer.AddAttribute(HtmlTextWriterAttribute.Src, "img.jd");
writer.AddAttribute("alt", "点击刷新");
}
}
public class AuthCodeHttpHander : IHttpHandler, IRequiresSessionState
{
/// <summary>
writer.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "pointer");//添加样式
writer.AddAttribute("onclick", "this.src='img.jd?id='+Math.random()");//添加js VerifyImg.jd
writer.AddAttribute(HtmlTextWriterAttribute.Src, "img.jd");
writer.AddAttribute("alt", "点击刷新");
}
}
public class AuthCodeHttpHander : IHttpHandler, IRequiresSessionState
{
/// <summary>
/// 返回验证码字符
/// </summary>
/// <param name="codeCount">验证码长度</param>
/// <returns></returns>
private string GetRandomNumberString(int codeCount)
{
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();
for (int i = 0; i < codeCount; i++)
{
int j = rnd.Next(strResult.Length);//随机数不能大于数组的长度
strReturn = strReturn + strResult[j].ToString();
/// </summary>
/// <param name="codeCount">验证码长度</param>
/// <returns></returns>
private string GetRandomNumberString(int codeCount)
{
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();
for (int i = 0; i < codeCount; i++)
{
int j = rnd.Next(strResult.Length);//随机数不能大于数组的长度
strReturn = strReturn + strResult[j].ToString();
}
return strReturn;
}
private Color GetColor()
{
return Color.Black;
}
private Bitmap CreateImage(string str_AuthCode)
{
int width = str_AuthCode.Length * 13;
int height = 20;
Random rad = new Random();
Bitmap bmp = new Bitmap(width, height);
return strReturn;
}
private Color GetColor()
{
return Color.Black;
}
private Bitmap CreateImage(string str_AuthCode)
{
int width = str_AuthCode.Length * 13;
int height = 20;
Random rad = new Random();
Bitmap bmp = new Bitmap(width, height);
Graphics grp = Graphics.FromImage(bmp);// 在图片上绘制图形
grp.Clear(Color.White);//填充bmp的背景
grp.DrawRectangle(new Pen(Color.Red, 1), 0, 0, width - 1, height - 1);//绘制边框
int num = width * height;
for (int i = 0; i < num; i+=3)//在图片的指定坐标上画上有颜的圆点
{
int x = rad.Next(width);
int y = rad.Next(height);
int r = rad.Next(255);
int g = rad.Next(255);
int b = rad.Next(255);
Color c = Color.FromArgb(r, g, b);
bmp.SetPixel(x, y, c);//在图片的指定坐标上画上有颜的圆点
}
grp.Clear(Color.White);//填充bmp的背景
grp.DrawRectangle(new Pen(Color.Red, 1), 0, 0, width - 1, height - 1);//绘制边框
int num = width * height;
for (int i = 0; i < num; i+=3)//在图片的指定坐标上画上有颜的圆点
{
int x = rad.Next(width);
int y = rad.Next(height);
int r = rad.Next(255);
int g = rad.Next(255);
int b = rad.Next(255);
Color c = Color.FromArgb(r, g, b);
bmp.SetPixel(x, y, c);//在图片的指定坐标上画上有颜的圆点
}
Font f = new Font("宋体", 12, FontStyle.Bold);//定义字体
Brush br = new SolidBrush(Color.Black);//定义画笔的颜及字体的颜
for (int i = 0; i < str_AuthCode.Length; i++)
{
string s = str_AuthCode.Substring(i, 1);//单个单个的将字画到图片上
Point p = new Point(i * 12 + rad.Next(3), rad.Next(3) + 1);//字体出现的位置(坐标)
grp.DrawString(s, f, br, p);//绘制字符串
}
grp.Dispose();
return bmp;//返回
}
/// <summary>
Brush br = new SolidBrush(Color.Black);//定义画笔的颜及字体的颜
for (int i = 0; i < str_AuthCode.Length; i++)
{
string s = str_AuthCode.Substring(i, 1);//单个单个的将字画到图片上
Point p = new Point(i * 12 + rad.Next(3), rad.Next(3) + 1);//字体出现的位置(坐标)
grp.DrawString(s, f, br, p);//绘制字符串
}
grp.Dispose();
return bmp;//返回
}
/// <summary>
/// 是否可以处理远程的HTTP请求
/// </summary>
public bool IsReusable
{
get { return true; }
}
/// <summary>
/// 将验证码图片发送给WEB浏览器
/// </summary>
/// <param name="context"></param>
public void ProcessRequest(HttpContext context)
{
int size = Size; //Int32.Parse((String)context.Session["Size"]);
MemoryStream ms = new MemoryStream(); // 创建内存流(初始长度为0 自动扩充)
/// </summary>
public bool IsReusable
{
get { return true; }
}
/// <summary>
/// 将验证码图片发送给WEB浏览器
/// </summary>
/// <param name="context"></param>
public void ProcessRequest(HttpContext context)
{
int size = Size; //Int32.Parse((String)context.Session["Size"]);
MemoryStream ms = new MemoryStream(); // 创建内存流(初始长度为0 自动扩充)
string NumStr = GetRandomNumberString(size);// 获得验证码字符
context.Session.Add("value", NumStr);//将验证码字符保存到session里面
Bitmap theBitmap = CreateImage(NumStr);// 获得验证码图片
theBitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);//将位图写入内存流
context.Response.ClearContent(); //清除缓冲区里的所有内容输出
context.Response.ContentType = "image/jpeg"; //需要输出图象信息 要修改HTTP头
context.Response.BinaryWrite(ms.ToArray()); //将内存流写入HTTP输出流
theBitmap.Dispose(); //释放资源
ms.Close();//释放资源
ms.Dispose();//释放资源
context.Response.End();
}
}
context.Session.Add("value", NumStr);//将验证码字符保存到session里面
Bitmap theBitmap = CreateImage(NumStr);// 获得验证码图片
theBitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);//将位图写入内存流
context.Response.ClearContent(); //清除缓冲区里的所有内容输出
context.Response.ContentType = "image/jpeg"; //需要输出图象信息 要修改HTTP头
context.Response.BinaryWrite(ms.ToArray()); //将内存流写入HTTP输出流
theBitmap.Dispose(); //释放资源
ms.Close();//释放资源
ms.Dispose();//释放资源
context.Response.End();
}
}
}
我是这样使用这个验证码控件的:
1:修改fig 文件
在 <system.web> </system.web>间加入下面的代码:
<httpHandlers>
<add verb="*" path="*.jd" type="AuthCode.AuthCodeHttpHander" />
</httpHandlers>
2: “开始”—“运行”—“cmd” ,用下面的两条命令编译AuthCode.cs文件为.DLL文件。(AuthCode.cs文件保存在“C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727”目录下) :
cd C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
csc /target:library AuthCode.cs
将得到的DLL文件添加到项目的引用中,在“工具箱”中右键点“选择项...”——在组件中勾选“AuthCode”(如下图),点确定之后工具箱中就会增加一个AuthCode控件。
cd C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
csc /target:library AuthCode.cs
将得到的DLL文件添加到项目的引用中,在“工具箱”中右键点“选择项...”——在组件中勾选“AuthCode”(如下图),点确定之后工具箱中就会增加一个AuthCode控件。
将这个控件从工具箱中拖到页面里使用。选中拖出的控件,在其属性中设置MySize即验证码的长度为某一正整数。例如设置成4,自动生成的代码如下(还有自动生成的注册这个控件的代码,这里未列出):
<cc1:AuthCode ID="AuthCode1" runat="server" MySize="4" />
到此,准备工作“基本”完成。(说“基本完成”是因为IIS里漏了一个必要的设置_^)
在.NET2005中通过“文件”—“打开”—“网站”—“本地IIS” 打开ASP.NET(C#)的网站项目,能正常运行页面,验证码控件生成的图片显示不了(只显示一个红叉)。 改用“文件系统”的形式打开则可以正常显示。这个问题我思考了好几天,还到一些技术论坛请教过别人,没人帮我解决(依靠别人是不行的)。这里只贴出那个最早的帖子的地址>>>,在编程论坛、编程爱好者上的帖子就不贴出来了。
我每天都试着去解决一下这个问题,终于慢慢到了问题的症结。 因为是在用IIS调试时出问题的,所以我猜测问题很有可能就出在IIS的某个设置上。
今天偶然发现IIS里有修改HTTP头的设置,而且上面的程序注释中提到了要修改HTTP头,语句如下:
context.Response.ContentType = "image/jpeg"; //需要输出图象信息 要修改HTTP头
同时,fig 文件中也有对“HTTP头”的设置,设置如下:
<httpHandlers>
<add verb="*" path="*.jd" type="AuthCode.AuthCodeHttpHander" />
</httpHandlers>
于是,我到MSDN里到了一些与<httphandlers>相关的资料,资料如下:
今天偶然发现IIS里有修改HTTP头的设置,而且上面的程序注释中提到了要修改HTTP头,语句如下:
context.Response.ContentType = "image/jpeg"; //需要输出图象信息 要修改HTTP头
同时,fig 文件中也有对“HTTP头”的设置,设置如下:
<httpHandlers>
<add verb="*" path="*.jd" type="AuthCode.AuthCodeHttpHander" />
</httpHandlers>
于是,我到MSDN里到了一些与<httphandlers>相关的资料,资料如下:
<httpHandlers> 设置由应用程序子目录继承。
<add> 指令按由上而下的顺序进行处理。如果两个或多个 <add> 元素指定相同的谓词/路径组合,则最后一个 <add> 会重写其他所有元素。
Microsoft Internet 信息服务 (IIS) 有自己的 ISAPI 映射扩展模型。为使给定应用程序扩展与其处理程序之间的映射生效,该扩展必须在 IIS 中映射为 ASP.NET ISAPI。对于自定义扩展等非标准扩展,则必须相应地配置 IIS。
受上面资料的启发,我又仔细翻查了IIS的设置,发现有个“映射”的设置。加上考虑到这个控件实际生成的是一个.jd的文件(没见过的扩展名...),所以我怀疑用IIS调试显示不了这个验证码图片的症结就在这里。
我以“<httpHandlers> IIS”为关键字百度了一下,经验证,终于到了准确有效的设置办法:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论