ASP.NET 實現圖型驗證碼

如何使用ASP.NET 實現圖型驗證碼呢? 看過來吧!

其實網路上已經有很多高手都發表過類似的文章,其實我也是參考那些文章做出來的,將結果寫在這邊跟大家分享一下.

首先我採用「泛型 Web 處理常式 (*.ashx)」來進行圖檔的輸出       ( 甚麼是aphx? )

驗證碼我採用Session來控制,也可以選擇採用Cache或是Cookie皆可,但是不建議使用Application喔!

ValidateCode.ashx 程式碼


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

using System;
using System.Web;
using System.Web.SessionState;
using System.Drawing;
using System.Collections.Generic;

public class ValidateCode : IHttpHandler, IRequiresSessionState
{
    
    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "image/png";
        this.CreateCheckCodeImage(GenerateCheckCode(context), context);

    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }

    #region 存取驗證碼
    private string CheckCode
    {
        set
        {
            HttpContext context = HttpContext.Current;
            if (context.Session["_ValCheckCode"] == null)
            {
                context.Session.Add("_ValCheckCode", value);
            }
            else
            {
                context.Session["_ValCheckCode"] = value;
            }
        }
        get
        {
            HttpContext context = HttpContext.Current;
            if (context.Session["_ValCheckCode"] == null)
            {
                return "";
            }
            else
            {
                return (string)context.Session["_ValCheckCode"];
            }            
        }
    }
    #endregion

    private int GetRandomCnt()
    {
        Random rd = new Random(DateTime.Now.Millisecond);
        return rd.Next(0, 6);
    }
    
    private string GenerateCheckCode(HttpContext context)
    {
        //設定隨機字元
        string str = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789";
        char[] chastr = str.ToCharArray();
        string code = "";
        Random rd = new Random();
        int i;
        
        //取出字數
        for (i = 0; i < 4; i++)
        {
            code += str.Substring(rd.Next(0, str.Length), 1);
        }
        
        //存入Session中
        this.CheckCode = code;
        
        return code;
    }
    
    private void CreateCheckCodeImage(string checkCode, HttpContext context)
    {
        #region 資源宣告
        string[] oFontName = {"Arial",
                              "Times New Roman", 
                              "MS Mincho", 
                              "Book Antiqua",
                              "Gungsuh", 
                              "PMingLiU", 
                              "Impact"};
        List<Color> oColor = new List<Color>();
        oColor.Add(Color.Black);
        oColor.Add(Color.Red);
        oColor.Add(Color.SteelBlue);
        oColor.Add(Color.Violet);
        oColor.Add(Color.Bisque);
        oColor.Add(Color.BurlyWood);
        oColor.Add(Color.Cyan);
        #endregion
        
        if (checkCode.Trim() == "" || checkCode == null)
            return;
        //設定圖片大小
        Bitmap image = new Bitmap(60, 23);
        
        Graphics g = Graphics.FromImage(image);
        try
        {            
            Random random = new Random();
            g.Clear(Color.White);
            //設定背景噪線
            int i;
            for (i = 0; i < 4; i++)
            {
                int x1 = random.Next(image.Width);
                int x2 = random.Next(image.Width);
                int y1 = random.Next(image.Height);
                int y2 = random.Next(image.Height);
                g.DrawLine(new Pen(oColor[GetRandomCnt()]), x1, y1, x2, y2);
            }
            
            Font font = new System.Drawing.Font(oFontName[GetRandomCnt()], 12, (System.Drawing.FontStyle.Italic));
            System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2F, true);
            g.DrawString(checkCode, font, brush, 2, 2);
            g.DrawRectangle(new Pen(Color.Black), 0, 0, image.Width - 1, image.Height - 1);
            
            //產生噪點
            for (i = 0; i < 40; i++)
            {
                image.SetPixel(random.Next(image.Width), random.Next(image.Height), oColor[GetRandomCnt()]);
            }
            
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
            context.Response.BinaryWrite(ms.ToArray());
        }
        catch
        {
            g.Dispose();
            image.Dispose();
        }
    }
}

 

進行Session取用及驗證的類別
Validation.cs


using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

/// <summary>
/// Validation 的摘要描述
/// </summary>
public class ValidationObject
{
    public ValidationObject()
	{
		//
		// TODO: 在此加入建構函式的程式碼
		//
    }

    #region < ValChkCode > 取得檢核碼
    public string ValChkCode
    {
        get
        {
            HttpContext context = HttpContext.Current;
            return context.Session["_ValCheckCode"] == null ? "" : context.Session["_ValCheckCode"] as string;
        }
    }
    #endregion

    #region [ Check ] 驗證檢核碼
    public bool Check(string sChkCode)
    {
        return sChkCode.Trim() == this.ValChkCode ? true : false;
    }
    #endregion
}

這邊說明一下ashx檔案開頭的地方我設定輸出的ContentType="image/png"所以會被視圖片檔來處理

在Web畫面上可以使用html的img標簽來展式或是使用asp.net的Image或ImageButton皆可

我在範例中是使用ImageButton來設定


<asp:ImageButton ID="ImageButton1" runat="server" width="80px" Height="23px"
            ImageUrl="~/ValidateCode.ashx" AlternateText="更換" />

參考資料 : [ASP.NET 控制項實作 Day28] 圖形驗證碼控制項

 

===========================這是簽名檔分隔線==============================
我沒有甚麼技術能力
不過卻希望在這邊跟大家分享自己遭遇的一些問題
希望大家有更好的方法可以跟我說!!
======================================================================