视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
asp.net 验证码的简单制作(vb.net+C#)
2020-11-27 22:42:29 责编:小采
文档

网站上验证码效果一般制作方法是:
1)使用HttpHandler(一般处理程序)绘制随机验证码的图,以及产生随机码,并输出到页面的OutputStream中。
2)页面中使用异步方式(js等)进行刷新当前页面的验证码。
【示例】
1)创建一个“一般应用处理程序ashx”,代码如下:
[C#]
代码如下:

public class ValidationCode : IHttpHandler
{
//随机发生器
static Random r = new Random(Guid.NewGuid().GetHashCode());
//排除黑色、透明色颜色,因为底色黑色
static PropertyInfo[] colors = (typeof(Brushes).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.Static)).Where(p => p.Name != "Black" && p.Name != "Transparent").Select(p => p).ToArray();
//排除黑色颜色,因为底色黑色
static PropertyInfo[] linecolors = (typeof(Pens).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.Static)).Where(p => p.Name != "Black").Select(p => p).ToArray();
//获取静态类Brushes实例对象
static object colorobj = typeof(Brushes).GetConstructor(BindingFlags.NonPublic, null, Type.EmptyTypes, null);
//获取静态类Pens实例对象
static object penobj = typeof(Pens).GetConstructor(BindingFlags.NonPublic, null, Type.EmptyTypes, null);
//每个随机字符的宽度
const float PERNUMBERWIDTH = 40.0f;
//每个字符的高度
const float PERNUMBERHEIGHT = 50.0f;
public void ProcessRequest(HttpContext context)
{
//获取要产生多少随机数(默认产生5个)
int reqNum = 5;
if (context.Request.QueryString["reqNum"] != null)
{
int.TryParse(context.Request.QueryString["reqNum"], out reqNum);
}
//产生多少大的背景图
Bitmap bt = new Bitmap((int)(PERNUMBERWIDTH*reqNum), (int)PERNUMBERHEIGHT);
Graphics g = Graphics.FromImage(bt);
//产生4个随机数(number可以被保存到Session中)
string numbers = "";
//绘制数字
for (int i = 1; i <= reqNum; i++)
{
numbers += r.Next(0, 9).ToString();
var color = (PropertyInfo)colors.GetValue(r.Next(0, colors.Length));
context.Response.Write(color.Name + "<br/>");
Brush randomcolor = (Brush)color.GetValue(colorobj, null);
g.DrawString(numbers[i-1].ToString(), new Font("黑体", PERNUMBERWIDTH),randomcolor, new PointF((i-1)*PERNUMBERWIDTH, 0f));
}
//绘制随机线条
int linenum = r.Next(10, 21);
for (int i = 1; i <= linenum; i++)
{
var linecolor = (PropertyInfo)linecolors.GetValue(r.Next(0, colors.Length));
Pen randomcolor = (Pen)linecolor.GetValue(penobj, null);
g.DrawLine(randomcolor, new PointF((float)(r.NextDouble() * PERNUMBERWIDTH * reqNum), (float)(r.NextDouble() * PERNUMBERHEIGHT)), new PointF((float)(r.NextDouble() * PERNUMBERWIDTH * reqNum), (float)(r.NextDouble() * PERNUMBERHEIGHT)));
}
g.Dispose();
context.Response.Clear();
context.Response.ContentType = "image/jpeg";
bt.Save(context.Response.OutputStream, ImageFormat.Jpeg);
bt.Dispose();
context.Response.End();
}
public bool IsReusable
{
get
{
return false;
}
}
}

[VB.NET]
代码如下:

Public Class ValidationCode
Implements IHttpHandler
'随机发生器
Shared r As New Random(Guid.NewGuid().GetHashCode())
'排除黑色、透明色颜色,因为底色黑色
Shared colors As PropertyInfo() = (GetType(Brushes).GetProperties(System.Reflection.BindingFlags.[Public] Or System.Reflection.BindingFlags.GetProperty Or System.Reflection.BindingFlags.[Static])).Where(Function(p) p.Name <> "Black" AndAlso p.Name <> "Transparent").[Select](Function(p) p).ToArray()
'排除黑色颜色,因为底色黑色
Shared linecolors As PropertyInfo() = (GetType(Pens).GetProperties(System.Reflection.BindingFlags.[Public] Or System.Reflection.BindingFlags.GetProperty Or System.Reflection.BindingFlags.[Static])).Where(Function(p) p.Name <> "Black").[Select](Function(p) p).ToArray()
'获取静态类Brushes实例对象
Shared colorobj As Object = GetType(Brushes).GetConstructor(BindingFlags.NonPublic, Nothing, Type.EmptyTypes, Nothing)
'获取静态类Pens实例对象
Shared penobj As Object = GetType(Pens).GetConstructor(BindingFlags.NonPublic, Nothing, Type.EmptyTypes, Nothing)
'每个随机字符的宽度
Const PERNUMBERWIDTH As Single = 40F
'每个字符的高度
Const PERNUMBERHEIGHT As Single = 50F
Public Sub ProcessRequest(context As HttpContext)
'获取要产生多少随机数(默认产生5个)
Dim reqNum As Integer = 5
If context.Request.QueryString("reqNum") IsNot Nothing Then
Integer.TryParse(context.Request.QueryString("reqNum"), reqNum)
End If
'产生多少大的背景图
Dim bt As New Bitmap(CInt(Math.Truncate(PERNUMBERWIDTH * reqNum)), CInt(Math.Truncate(PERNUMBERHEIGHT)))
Dim g As Graphics = Graphics.FromImage(bt)
'产生4个随机数(number可以被保存到Session中)
Dim numbers As String = ""
'绘制数字
For i As Integer = 1 To reqNum
numbers += r.[Next](0, 9).ToString()
Dim color = DirectCast(colors.GetValue(r.[Next](0, colors.Length)), PropertyInfo)
context.Response.Write(Convert.ToString(color.Name) & "<br/>")
Dim randomcolor As Brush = DirectCast(color.GetValue(colorobj, Nothing), Brush)
g.DrawString(numbers(i - 1).ToString(), New Font("黑体", PERNUMBERWIDTH), randomcolor, New PointF((i - 1) * PERNUMBERWIDTH, 0F))
Next
'绘制随机线条
Dim linenum As Integer = r.[Next](10, 21)
For i As Integer = 1 To linenum
Dim linecolor = DirectCast(linecolors.GetValue(r.[Next](0, colors.Length)), PropertyInfo)
Dim randomcolor As Pen = DirectCast(linecolor.GetValue(penobj, Nothing), Pen)
g.DrawLine(randomcolor, New PointF(CSng(r.NextDouble() * PERNUMBERWIDTH * reqNum), CSng(r.NextDouble() * PERNUMBERHEIGHT)), New PointF(CSng(r.NextDouble() * PERNUMBERWIDTH * reqNum), CSng(r.NextDouble() * PERNUMBERHEIGHT)))
Next
g.Dispose()
context.Response.Clear()
context.Response.ContentType = "image/jpeg"
bt.Save(context.Response.OutputStream, ImageFormat.Jpeg)
bt.Dispose()
context.Response.[End]()
End Sub
Public ReadOnly Property IsReusable() As Boolean
Get
Return False
End Get
End Property
End Class

注意:
1)一些诸如Brushes等特定因为是公用的,需要通过反射获取全部的颜色属性列表,因此使用了静态变量,这样不必每次都初始化,节省内存和时间。
2)Brushes避免黑色和透明色(本示例背景色是黑色),Pens只需避免黑色即可。有关Brushes颜色,可以查阅:http://msdn.microsoft.com/zh-cn/library/system.windows.media.brush(v=vs.95).aspx
3)Bitmap类是用于绘制使用的,一般是空白的黑色背景。一般配合Image类+Graphics画布使用,进行绘制。
4)BitMap的Save方法有若干个重载版本,其中之一可以指定
输出流以及设置图片格式。本示例就是使用了这个函数。
【应用】

Html中代码(验证码部分,局部):
代码如下:

<h1>
验证码
</h1>
<script>
function ChangeSD() {
document.getElementById("imgSD").src = "";
document.getElementById("imgSD").src = "/ValidationCode.ashx?reqNum=10";
};
</script>
<img src="https://www.gxlcms.com/ValidationCode.ashx?reqNum=10" id="imgSD" />
<input type="button" value="Change Validation Key" onclick="ChangeSD()" />

注意,之所以使用js设置img的src两次,是因为重复的路径不会引发请求。

下载本文
显示全文
专题