La méthode générale pour créer des effets de code de vérification sur le site Web est la suivante :
1) Utilisez HttpHandler (gestionnaire général) pour dessiner une image de code de vérification aléatoire, générer un code aléatoire et l'envoyer vers le OutputStream de la page.
2) Utilisez la méthode asynchrone (js, etc.) dans la page pour actualiser le code de vérification de la page actuelle.
[Exemple]
1) Créez un "gestionnaire d'application général ashx" avec le code suivant :
[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
Remarque :
1) Certains pinceaux spécifiques tels que les pinceaux sont publics et doivent obtenir la liste complète des attributs de couleur par réflexion, donc des variables statiques sont utilisées afin qu'elles n'aient pas besoin d'être initialisées à chaque fois, économisant ainsi de la mémoire et temps.
2) Les pinceaux évitent les couleurs noires et transparentes (la couleur de fond dans cet exemple est le noir), et les stylos doivent uniquement éviter le noir. Pour les couleurs des pinceaux, vous pouvez vérifier : http://msdn.microsoft.com/zh-cn/library/system.windows.media.brush(v=vs.95).aspx
3) La classe Bitmap est utilisée pour dessiner Ce qui est utilisé est généralement un fond noir vierge. Généralement utilisé avec le canevas Graphics de la classe Image pour le dessin.
4) La méthode Save de BitMap a plusieurs versions surchargées, dont l'une peut spécifier le flux de sortie et définir le format de l'image. Cet exemple utilise cette fonction.
【Application】
Code HTML (partie du code de vérification, partielle) :
<h1> 验证码 </h1> <script> function ChangeSD() { document.getElementById("imgSD").src = ""; document.getElementById("imgSD").src = "/ValidationCode.ashx?reqNum=10"; }; </script> <img src="/ValidationCode.ashx?reqNum=10" id="imgSD" /> <input type="button" value="Change Validation Key" onclick="ChangeSD()" />
Notez que la raison pour laquelle js est utilisé pour définir img src deux fois car les chemins répétés ne déclencheront pas de requêtes.
Pour plus d'articles liés à la production simple de code de vérification asp.net (vb.net C#), veuillez faire attention au site Web PHP chinois !