Introduction

This article describes how to create a custom control in ASP.NET for implementing image verification functionality. What is image verification? You might have
seen this implemented in many websites like microsoft.com, google.com, yahoo.com, etc., during the signup process. It's simply used for verifying the user's input,
by validating the code which the user enters against a random code displayed as image in the form. This helps the application to identify automated submission of forms
and reject such requests which could even crash the web site by inputting bulk data to the site.

Background

I saw this functionality implemented in various sites and thought of implementing it while creating a personal website. When I started implementing
the functionality in my site, I faced a few issues. Some of them generated random text, persisting the text so that it can be verified against the user input
code during post backs, avoid storing the generated code in viewstate or URLs etc. Gradually I found solutions to these issues. I will be explaining those solutions in the sections below.

Key Points

Explaining every piece of code used in the sample application is difficult to do in this article. Hence I will explain the following key steps involved
in the development of this custom control.

Create a custom control capable of rendering <img> tags.

Generate a random text, persist it, and render it as image.

Verify the user input against the persisted random text.

Create a custom control to render <Img> tags

First of all, we need to create a custom control which can render the standard HTML <img> tags. It should also generate a dynamic URL and attach
it to the src attribute of the <img> tag generated.

This is done in the example by deriving a class named ImageVerifier from WebControl, as shown below.

In addition to deriving the control from WebControl, I have implemented IHttpHandler too in that class. This is for making the control
render the image itself in addition to the normal <img> tag rendering.

The first line in the Render method assigns the src attribute for the rendered <img> tag. It generates the URL
in the format "ImageVerifier.axd?uid=" + this.MyUniqueID. The control has a property MyUniqueID which will be a unique GUID generated
for each control instance. The last line of the Render method outputs a hyperlink to refresh the image without postback.

Generate a random text, persist it, and render it as image

For rendering a dynamic text as the image of this control, we will be using the same class ImageVerifier through the implementation of the IHttpHandler method
public void ProcessRequest(HttpContext context). This method will be called when the browser requests the URL specified in the src attribute
of the <img> tag rendered. In order to make this happen, we need to configure our ImageVerifier class as an HTTPHandler for URLs
like ImageVerifier.axd in the web.config file of the consuming application.

In the ProcessRequest() method, a random text is generated using the private method GetRandomText() and is persisted using the Cache object
as shown above. The value of the query string uid will be used as the key for persisting the random text in the Cache object.

For generating random text of a specific length, we can write custom logic. Here in the sample, I have used the Random class to generate
random numbers and convert them to the corresponding characters. The same logic can be implemented in different ways as you wish.

Verify user input against the persisted random text

Finally, we need to validate the user input against the random text which is displayed as the image. For this, I have added a Text property for our user control.
This property retrieves the random text stored in the Cache and returns it. We can use this value to verify the user input.

The code below shows an example of the code to be implemented in the consuming application for verifying the user input.

protectedvoid btnSubmit_Click(object sender, EventArgs e)
{
if (txtImgVerifyText.Text == ImageVerifier1.Text)
{
// User has input the correct text so can continue
// processing the request.
}
else
{
// Either user has input an incorrect value or the request
// is not generated by the manual input. So do not continue
// processing the request.
}
}

Points of interest

In this article, I explained how to use the concept of image verification to help applications in identifying automated submission of forms. The implementation
of this image verification used a few coding concepts such as HTTPHandlers, Random class, Cache object, etc.

I do have a few suggestions.0) I renamed my_uniqueKey to SessionKey to better fit it's purpose.1) Do not store the generated code in the session, store it's hashValue.2) Add a validation method to test the input:

By the time it comes to Process Request method, all the values in the viewstate are becoming null,therefore i stored the values in a cache. Sometimes it works fine and sometimes the values in cache becomes null :(

There is one little bug. After refreshing the image, and then post back, the image will go back to previous generated image. In other words, after refreshing image, the generated image is lost after any post back. Any solutions?

I downloaded ... this project, but I can't run. This project alert:"Error - Parser Error: Unknown server tag 'cc1:imageverifier'." . And then, I open Design the file Default.aspx by VS05, but can't open. Can you tell me, how to use this project. this is the alert detail, which i have: "Can not switch to design view because of Error in the page. Please correct all errors labeled'can not switch': in the error list and try again"Thanks

The error "Can not switch to design view because of Error in the page. Please correct all errors labeled'can not switch" is due to the multiple style attributes I added for the html table in the default.aspx. If you make it to a single style attribute it should work.

Regarding the project alert :"Error - Parser Error: Unknown server tag 'cc1:imageverifier'". Did you try opening the solution file or the website project alone? If you have opened the website, then please open the solution file and build the solution again. Please let me know if it is not solving your issue.

All most anything you do will be insignificant but it is very important that you do it. - Gandhiji