Sunday, March 4, 2012

How to create image verification for user registration in asp.net

Often, we have to use image verification for sign up in our application to prevent the automated registrations. This is essential because someone may send a lot of request programmatically to your server so that to slow down the speed of your server and making the size of your database large and large by entering much nuisance information. By creating the image verification on sign up page, it can reduces system loads and make better performance and security of your web site.
This sample is about how you can verify user sign up while registering a user to your web site look like Yahoo and Google.
Imag verification on sign up page
First we create ImageVerifyTest.aspx (such as Sign Up page) and put the following code to <form> tag. It use "UpdatePanel" for image so that don't refresh the whole page while clicking "Try a different image" button.
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
    <table cellpadding="2" cellspacing="0">
        <tr>
            <td align="right">
                <asp:Label ID="Label5" runat="server" Text="Type the code shown"></asp:Label>
            </td>
            <td></td>
            <td>
                <asp:TextBox ID="txtImgVerify" runat="server" Text=""></asp:TextBox>
                <asp:Label ID="lblVerifyMsg" runat="server" Font-Bold="True" ForeColor="Red" Text="*"
                    Visible="False"></asp:Label>
            </td>
        </tr>
        <tr>
            <td align="right">
                <asp:LinkButton ID="lnkBtnImgVerify" runat="server" ForeColor="Blue" OnClick="lnkBtnImgVerify_Click"
                    Text="Try a different image" ValidationGroup="try"></asp:LinkButton>
            </td>
            <td></td>
            <td style="height: 50px;">
                <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
                    <ContentTemplate>
                        <asp:Image ID="imgVerify" runat="server" ImageUrl="imageVerify.aspx" />
                    </ContentTemplate>
                    <Triggers>
                        <asp:AsyncPostBackTrigger ControlID="lnkBtnImgVerify" EventName="Click"></asp:AsyncPostBackTrigger>
                    </Triggers>
                </asp:UpdatePanel>
            </td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td>
                <asp:Button ID="btnGo" runat="server" onclick="btnGo_Click" Text="Go"
                    Width="56px" />
            </td>
        </tr>
    </table>
</div>
</form>

And add the snippet code as below in code-behind.
protected void lnkBtnImgVerify_Click(object sender, EventArgs e)
{
    try
    {
        lblVerifyMsg.Visible = false;
        imgVerify.ImageUrl = "imageVerify.aspx";
    }
    catch (Exception ex) { }
}
protected void btnGo_Click(object sender, EventArgs e)
{
    //check image verification here
    if (!Session["CheckCode"].ToString().Equals(txtImgVerify.Text.Trim()))
    {
        lblVerifyMsg.Visible = true;
        return;
    }
    else
    {
        //here go on process after successful verification
    }
}

Second, create ImageVerify.aspx (for image) and put the code to code-behind as below.
using System.Drawing;
public partial class ImageVerify : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            string checkCode = string.Empty;
            checkCode = CreateRandomCode(6);
            Session["CheckCode"] = checkCode;
            CreateImage(checkCode);
        }
        catch (Exception ex)
        {}
    }
    private void CreateImage(string checkCode)
    {
        Bitmap image = new System.Drawing.Bitmap(Convert.ToInt32(Math.Ceiling((decimal)(checkCode.Length * 19))), 50);
        Graphics g = Graphics.FromImage(image);
        try
        {
            Random random = new Random();
            g.Clear(Color.AliceBlue);
            for (int i = 0; i < 25; 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(Color.Silver), x1, y1, x2, y2);
            }
            Font font = new System.Drawing.Font("Comic Sans MS", 15, System.Drawing.FontStyle.Regular);
            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, new SolidBrush(Color.Green), 10, 10);
            for (int i = 0; i < 100; i++)
            {
                int x = random.Next(image.Width);
                int y = random.Next(image.Height);

                image.SetPixel(x, y, Color.FromArgb(random.Next()));
            }
            g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
            Response.ClearContent();
            Response.ContentType = "image/Gif";
            Response.BinaryWrite(ms.ToArray());
        }
        finally
        {
            g.Dispose();
            image.Dispose();
        }
    }
    public string CreateRandomCode(int codeCount)
    {
        string randomCode = "";
        try
        {
            string allChar = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
            string[] allCharArray = allChar.Split(',');
            int temp = -1;
            Random rand = new Random();
            for (int i = 0; i < codeCount; i++)
            {
                if (temp != -1)
                {
                    rand = new Random(i * temp * ((int)DateTime.Now.Ticks));
                }
                int t = rand.Next(26);
                if (temp != -1 && temp == t)
                {
                    return createRandomCode(codeCount);
                }
                temp = t;
                randomCode += allCharArray[t];
            }
            return randomCode;
        }
        catch (Exception ex)
        {
            return randomCode;
        }
    }
}

Run your application and enter the characters shown in the image and click the Go button to verify the characters. Safety Frist! :)

2 comments:

  1. GREAT POST, the only issue I'm having is that the "lnkBtnImgVerify" is not updating the image. Any thoughts on what the issue could be?

    ReplyDelete
  2. Sorry, I found it out that it don't work in IE. I will post solution for this case later. Thank.

    ReplyDelete