首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

ASP.NET 圖形驗證碼生成完整範例:GDI+ 繪圖、Session 儲存與前端整合

     編輯:關於ASP.NET

驗證碼核心原理

  1. 隨機產生字串 (字母數字混合)。
  2. 字串存入 `Session["RandCode"]` 供後續驗證。
  3. 使用 `System.Drawing` 繪製干擾線、雜點、文字至 `Bitmap`。
  4. 輸出 `image/gif` 位元組流至 `Response.BinaryWrite`。
  5. 前端 `` 載入,點擊重新整理。

完整後台程式碼 (VerifyCode.aspx.cs)

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Web.UI;

public partial class VerifyCode : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // 防止快取
        Response.Cache.SetNoStore();
        Response.Cache.SetExpires(DateTime.MinValue);

        GenerateImage();
    }

    private void GenerateImage()
    {
        const int width = 71, height = 23;
        using (var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb))
        using (var g = Graphics.FromImage(bmp))
        {
            var rand = new Random();

            // 1. 背景
            g.Clear(Color.White);

            // 2. 干擾線
            for (int i = 0; i < 50; i++)
            {
                using (var pen = new Pen(Color.FromArgb(rand.Next(256), rand.Next(256), rand.Next(256))))
                {
                    g.DrawLine(pen, rand.Next(width), rand.Next(height), rand.Next(width), rand.Next(height));
                }
            }

            // 3. 干擾點
            for (int i = 0; i < 100; i++)
            {
                bmp.SetPixel(rand.Next(width), rand.Next(height), Color.FromArgb(rand.Next(256), rand.Next(256), rand.Next(256)));
            }

            // 4. 產生隨機碼
            string code = GenerateRandomCode(5);
            Session["RandCode"] = code; // 存入 Session

            // 5. 繪製文字
            using (var font = new Font("Arial", 14, FontStyle.Bold))
            using (var brush = new LinearGradientBrush(
                new Rectangle(0, 0, width, height),
                Color.Red, Color.Blue, 1.2f, true))
            {
                int yOffset = rand.Next(1, 4);
                g.DrawString(code, font, brush, 2, yOffset);
            }

            // 6. 邊框
            g.DrawRectangle(Pens.Silver, 0, 0, width - 1, height - 1);

            // 7. 輸出
            using (var ms = new MemoryStream())
            {
                bmp.Save(ms, ImageFormat.Gif);
                Response.ClearContent();
                Response.ContentType = "image/gif";
                Response.BinaryWrite(ms.ToArray());
            }
        }
    }

    private static readonly char[] _chars = "0123456789abcdefghijklmnopqrstuvwxyz".ToCharArray();

    private string GenerateRandomCode(int length)
    {
        var rand = new Random();
        var sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) sb.Append(_chars[rand.Next(_chars.Length)]);
        return sb.ToString();
    }
}

前端使用方式

<asp:Image ID="imgVerify" runat="server" ImageUrl="~/VerifyCode.aspx" Style="cursor:pointer; vertical-align:middle;" />
<a href="javascript:void(0);" onclick="document.getElementById('<%=imgVerify.ClientID%>').src='VerifyCode.aspx?t='+Date.now();">看不清?換一張</a>
<br />
<asp:TextBox ID="txtCode" runat="server" MaxLength="5" />
<asp:Button ID="btnSubmit" runat="server" Text="提交" OnClick="btnSubmit_Click" />

驗證邏輯

protected void btnSubmit_Click(object sender, EventArgs e)
{
    string userCode = txtCode.Text.Trim().ToLower();
    string sessionCode = (Session["RandCode"] as string)?.ToLower();

    if (string.Equals(userCode, sessionCode))
    {
        lblResult.Text = "驗證通過!";
        // 移除 Session 防止重複使用
        Session.Remove("RandCode");
    }
    else
    {
        lblResult.Text = "驗證碼錯誤,請重新輸入。";
    }
}

進階強化方向

方向做法
字型多樣化隨機選擇字型、字體大小、旋轉角度 (`g.RotateTransform`)
中文驗證碼字元集改為常用漢字,字型需支援中文 (如「微軟正黑體」)
語音驗證碼產生語音檔 (TTS) 回傳 `audio/mp3`,無障礙支援
滑動/點選驗證前端 Canvas/JS 互動,後端驗證軌跡/點選座標
分散式 SessionWeb Farm 環境下使用 Redis/DB 儲存驗證碼,避免 InProc Session 遺失

常見問題

  • GDI+ 通用錯誤:`Response.BinaryWrite` 後不可再有輸出。確保 `Response.End()` 或頁面無其他輸出。
  • Session 遺失:`EnableSessionState="true"` (預設),確認 Cookie 能正常寫入 (P3P 標頭、SameSite 設定)。
  • 高並發效能:GDI+ 非執行緒安全,大量並發建議改用 `ImageSharp` (純 managed) 或專用驗證碼服務。

總結

ASP.NET 圖形驗證碼核心在於 `Bitmap` + `Graphics` 繪製、`Session` 狀態同步、`Response.BinaryWrite` 圖片流輸出。範例提供可直接部署的完整程式碼,並指出進階強化與生產環境注意事項。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved