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

開發基於 ASP.NET WebService 的圖片驗證碼服務:從 Bitmap 到位元組流的完整實作

     編輯:關於ASP.NET

需求背景

頁面需驗證碼防止惡意提交。方案:WebService 方法回傳驗證碼圖片位元組陣列 (`byte[]`),前端 `` 標籤指向 `.asmx` 或 `.ashx` 取得圖片,驗證碼文字存入 Session 驗證。

核心技術點

  1. 隨機產生圖片:`System.Drawing.Bitmap` + `Graphics` 繪製背景、干擾線、雜點、文字。
  2. WebService 傳遞圖片:`Bitmap` → `MemoryStream` → `byte[]` 回傳,SOAP 自動序列化為 base64。
  3. 驗證碼儲存與驗證:產生時存入 `Session["VerifyCode"]`,使用者提交時比對 (忽略大小寫)。

完整 WebService 實作

[WebService(Namespace = "https://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService] // 允許 AJAX 呼叫
public class VerifyCodeService : System.Web.Services.WebService
{
    [WebMethod(EnableSession = true)] // 需啟用 Session
    public byte[] GenerateVerifyImage(int length, out string verifyCode)
    {
        // 1. 參數檢查
        if (length < 1 || length > 10) length = 4;

        // 2. 產生隨機驗證碼
        const string chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; // 排除易混淆字元
        var rand = new Random();
        var codeChars = new char[length];
        for (int i = 0; i < length; i++) codeChars[i] = chars[rand.Next(chars.Length)];
        verifyCode = new string(codeChars);

        // 3. 儲存至 Session (供後續驗證)
        Context.Session["VerifyCode"] = verifyCode.ToUpper();

        // 4. 繪製圖片
        int width = 13 * length + 10;
        int height = 28;
        using (var bmp = new Bitmap(width, height))
        using (var g = Graphics.FromImage(bmp))
        {
            // 背景
            g.Clear(Color.White);

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

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

            // 文字
            using (var font = new Font("Consolas", 16, FontStyle.Bold | FontStyle.Italic))
            using (var brush = new SolidBrush(Color.FromArgb(rand.Next(0, 100), rand.Next(0, 100), rand.Next(0, 100))))
            {
                for (int i = 0; i < length; i++)
                {
                    float x = 5 + i * 13 + rand.Next(-1, 2);
                    float y = 2 + rand.Next(-1, 2);
                    g.DrawString(codeChars[i].ToString(), font, brush, x, y);
                }
            }

            // 輸出為 byte[]
            using (var ms = new MemoryStream())
            {
                bmp.Save(ms, ImageFormat.Gif);
                return ms.ToArray();
            }
        }
    }

    [WebMethod(EnableSession = true)]
    public bool ValidateVerifyCode(string userInput)
    {
        string code = Context.Session["VerifyCode"] as string;
        if (string.IsNullOrEmpty(code)) return false;
        return string.Equals(code, userInput?.ToUpper(), StringComparison.OrdinalIgnoreCase);
    }
}

前端呼叫方式

傳統 ASMX 直接當圖片來源

<img id="imgVerify" src="VerifyCodeService.asmx/GenerateVerifyImage?length=4" alt="驗證碼" style="cursor:pointer" onclick="this.src=this.src.split('?')[0]+'?length=4&t='+Date.now()" />

AJAX 呼叫 (jQuery) 取得 base64 顯示

$.ajax({
    type: "POST",
    url: "VerifyCodeService.asmx/GenerateVerifyImage",
    data: JSON.stringify({ length: 4 }),
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function (resp) {
        // resp.d 為 base64 字串 (byte[] 自動轉換)
        $("#imgVerify").attr("src", "data:image/gif;base64," + resp.d);
    }
});

表單驗證

$.post("VerifyCodeService.asmx/ValidateVerifyCode", { userInput: $("#txtCode").val() }, function(resp) {
    if (resp.d) { /* 通過 */ } else { /* 失敗,重新整理圖片 */ }
});

部署注意事項

  • IIS 應用程式集區身分需具備 `C:\Windows\Temp` 寫入權限 (GDI+ 需要)。
  • 生產環境建議改用 **Generic Handler (.ashx)** 或 **ASP.NET Core Middleware**,效能優於 ASMX。
  • 驗證碼長度 4-6 碼,字元集排除 0/O、1/I、8/B 等易混淆字元。
  • 加入語音驗證碼、滑動拼圖等無障礙替代方案。

總結

ASP.NET WebService 結合 `System.Drawing` 實作驗證碼服務,核心在於 `Bitmap` 繪圖、`MemoryStream` 序列化為 `byte[]`、Session 儲存驗證碼。雖 ASMX 屬舊技術,但原理通用於現代 ASP.NET Core 檔案流回傳與驗證邏輯。

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