ASP.Net – Xuất tập tin aspx thành ảnh captcha

ASP_NetĐây không phải là vấn đề mới chỉ có mục đích bổ sung cho bài viết Tạo captcha đơn giản cho trang web với ASP.Net. Trong bài này bạn sẽ được biết thêm cách để đổi phần mở rộng của tập tin aspx mà vẫn giữ nguyên đặc tính của nó. Tôi sẽ dùng phương pháp này để biến một tập tin aspx thành một tập tin ảnh captcha ra trang web.

Download DemoCaptcha.rar (VWD 2008)

Đầu tiên bạn trang chính Default.aspx và thiết kế như sau.

Default.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Image ID="imgCaptcha" runat="server" ImageUrl="Captcha.gif" />
        <asp:ImageButton ID="imbReLoad" runat="server" ImageUrl="~/Images/reload.png"
            Height="24px" Width="24px" /><br />
        <asp:TextBox runat="Server" ID="txtCaptcha" />&nbsp;<br />
        <asp:Button runat="Server" ID="btnSubmit" Text="Đồng ý" OnClick="btnSubmit_Click" />
        <br />
        <asp:Label ID="lblMessage" runat="server" ForeColor="Red"></asp:Label></div>
    </form>
</body>
</html>

Trong code-behind:

Default.aspx.cs:

using System;
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;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        if (txtCaptcha.Text.Equals(Session["captcha"].ToString(), StringComparison.OrdinalIgnoreCase))
            lblMessage.Text = "Chuỗi xác nhận chính xác";
        else
            lblMessage.Text = "Vui lòng nhập đúng chuỗi xác nhận";
    }
}

Tiếp theo bạn thêm một WebForm mới. Tên của file này bạn sẽ đặt phần mở rộng là .gif, và bỏ tùy chọn Place code in separate file để viết code-inline và code-behind chung trong một file duy nhất, như hình sau:

Add Captcha aspx file

Tiếp đến bạn import các namespace cần thiết và viết code cho sự kiện Page_Load, mã nguồn hoàn chỉnh của trang như sau:

Captcha.gif:

<%@ Page Language="C#" %>

<%@ Import Namespace="System.Drawing" %>
<%@ Import Namespace="System.Drawing.Drawing2D" %>
<%@ Import Namespace="System.IO" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        string[] fonts = { "Arial Black", "Lucida Sans Unicode", "Comic Sans MS" };

        const byte LENGTH = 5;

        // chuỗi để lấy các kí tự sẽ sử dụng cho captcha
        const string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

        using (Bitmap bmp = new Bitmap(120, 30))
        {
            using (Graphics g = Graphics.FromImage(bmp))
            {
                // Tạo nền cho ảnh dạng sóng
                HatchBrush brush = new HatchBrush(HatchStyle.Wave, Color.White, Color.Wheat);
                g.FillRegion(brush, g.Clip);

                // Lưu chuỗi captcha trong quá trình tạo
                StringBuilder strCaptcha = new StringBuilder();

                Random rand = new Random();

                for (int i = 0; i < LENGTH; i++)
                {
                    // Lấy kí tự ngẫu nhiên từ mảng chars
                    string str = chars[rand.Next(chars.Length)].ToString();
                    strCaptcha.Append(str);

                    // Tạo font với tên font ngẫu nhiên chọn từ mảng fonts
                    System.Drawing.Font font = new Font(fonts[rand.Next(fonts.Length)], 12, FontStyle.Strikeout | FontStyle.Italic);

                    // Lấy kích thước của kí tự
                    SizeF size = g.MeasureString(str, font);

                    // Vẽ kí tự đó ra ảnh tại vị trí tăng dần theo i, vị trí top ngẫu nhiên
                    g.DrawString(str, font,
                    Brushes.Chocolate, i * size.Width + 3, rand.Next(2, 10));
                    font.Dispose();
                }

                // Lưu captcha vào session
                Session["captcha"] = strCaptcha.ToString();

                // Ghi ảnh trực tiếp ra luồng xuất theo định dạng gif
                Response.ContentType = "image/GIF";
                bmp.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);
            }
        }
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    </div>
    </form>
</body>
</html>

Mã nguồn tương tự như trong bài trước tôi trình bày, tuy nhiên khi chạy thử thì hình ảnh captcha sẽ không hiển thị được vì server không thực hiện phương thức Page_Load của file Captcha.gif.  Để khắc phục ta cần đăng kí phần mở rộng mới này vào tập tin web.config để nó được “đối xử” như một tập tin aspx thông thường.

Có hai khái niệm ta cần tìm hiểu trước khi tiếp tục:

–       HTTP Handler: Các thành phần thuộc dạng này được hiện thực từ interface System.Web.IHttpHandle, điều này cho phép chúng được phép nhận các request với giao thức  HTTP, và chúng được gọi trực tiếp dựa vào tên tập tin.

–       Build Provider: thành phần này định nghĩa các loại file và tài nguyên sẽ được biên dịch. Trong tập tin web.config bạn có thể không thấy các định nghĩa này vì chúng được thiết lập mặc định các kiểu file như aspx, ascx, master,…

Bây giờ ta bắt đầu thực hành hai khái niệm trên để đăng kí phần mở rộng .gif cho dự án này.

Bạn mở tập tin web.config, tìm thẻ <httpHandlers> và thêm một thẻ con vào như sau:

<httpHandlers>
	<add verb="*" path="*.gif" type="System.Web.UI.PageHandlerFactory"/>
[…]
</httpHandlers>

Trong thẻ <compilation> thêm các dòng được highlight sau vào:

<compilation debug="true">
	<assemblies>
	[…]
	</assemblies>
	<buildProviders>
		<add extension=".gif" type="System.Web.Compilation.PageBuildProvider"/>
	</buildProviders>
</compilation>

Vậy là xong, bạn có thể chạy thử và xem kết quả như hình sau:

Demo Captcha

Việc lưu hay xuất 1 tập tin xuống client cũng có cách làm cũng tương tự như trong bài này, dùng Response để xuất nội dung ra (nhị phân hoặc text) và tất nhiên do tính bảo mật bạn không thể lưu “âm thầm” hay chay file được.

https://yinyangit.wordpress.com

Advertisements

5 thoughts on “ASP.Net – Xuất tập tin aspx thành ảnh captcha

Trả lời

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s