How to Add Simple Captcha in C# Part One

Category: ASP.NET

 

How to add a basic Captcha Service in C# [Part One]


Introduction

This article is Part One in a two-part series. Click here to read Part Two.

In this article we will explain how you can easily create a web service within Visual Studio 2005 that will function as a Captcha Image service that will dispense Captcha images as needed from any application that consumes the service.

We migrated our web sites to Server Intellect over one weekend and the setup was so smooth that we were up and running right away. They assisted us with everything we needed to do for all of our applications. With Server Intellect's help, we were able to avoid any headaches!

This is a basic example of a Captcha service but it is fully functional and will dynamically create the Captcha image and dispense it back to the calling application in a [Base64] encoded byte array that can then be converted into an image through your client side code very easily. In the next part of this series we will be designing an application that will utilize this web service and display the Captcha image.
The text on the image is created on the client side and passed to this web service from the client application. The images are stored in the web service directory and a new image and control code are created each time and passed back to the client side application.

What is a Web Service
Before we begin let me explain briefly what a Web Service is.
Web Services are utilized in the design of SOA architectures and as part of the foundation for that architecture. SOA means Service Oriented Architecture.
In simplistic terms and using only one example of what web services are utilized for we are designing a layer between the front end [client side application] and the back end data layer. In this instance it is a web service, which is usually sitting on top of a database, but in this example instead of serving up data we are serving up dynamic images.
Web services are usually public facing and allow users with internet/network access to retrieve information in a disconnected process.
I mention internet and network in the sense that you can have a public facing web service that can be accessed via the internet and part of your internet based web site. The Network mention refers to many corporations that have web services within their intranet that will return record sets of data or documents needed to maintain their daily operation.
There are many facets to web services and the many ways they can benefit a corporation or a developer.

 

 

What we will learn in this article:

  • How to Create a Web Service
  • How to return a Captcha Image Byte Array from this Web Service

Getting Started
We will take you through the process of creating this Web Service using Microsoft Visual Studio 2005 and C#.

We moved our web sites to Server Intellect and have found them to be incredibly professional. Their setup is very easy and we were up and running in no time.

Source Code for the Web Service
Start Visual Studio 2005 and create a new Web Service project as illustrated in Fig. 1:


[Click to see full-size]



When you select the “OK” button the project will be created. We will replace the generated source code by the designer with the source code that makes up the Captcha image web service; this code will be replaced in the Service1.asmx file that is created from the above example.

 

public byte[] GetCaptchaImage(string imageText)
{
return ReadBytes(Server.MapPath(GenerateCaptchaImage(imageText)));
}

This example code contains a “Public” method called “GetCaptchaImage(string imageText)” that returns the byte array of the Captcha image with the code control characters displayed on the image. These code control characters are found in the “imageText” argument passed to this method. This is the only “Public” method within this web service, all of the other methods that make up this web service are private methods and cannot be accessed by the client side application. These can be made accessible by turning the declaration from “Private” to “Public” and regenerating the web service proxy for your client side application if you ever need to access any of these methods.

public byte[] GetCaptchaImage(string imageText)
{
return ReadBytes(Server.MapPath(GenerateCaptchaImage(imageText)));
}

The next method we will use is the “ReadBytes(string fileName)” method, this method will open the image file name passed to it called “imageBack.jpg” and read the contents of that file into a byte array to be used for writing the Captcha control code we will be using. This file can be found in the “Images” directory”

private byte[] ReadBytes(string fileName)
{
byte[] b = new byte[0];

if (File.Exists(fileName))
{
try
{
FileStream s = File.OpenRead(fileName);
byte[] bytes = new byte[s.Length];
s.Read(bytes, (int)0, (int)s.Length);
b = bytes;
}
catch (IOException e)
{
throw new IOException(e.Message);
}
}

return b;
}

Need help with Windows Dedicated Hosting? Try Server Intellect. I'm a happy customer!

This method is called “GenerateCaptchaImage(string imageText)”. This method will open the image file and generate the Captcha image along with the control code characters displayed on that image. Those control code characters are displayed based on the argument passed to this method.

private String GenerateCaptchaImage(string imageText)
{
Font imgFont;
int iIterate;
Bitmap raster;

Graphics graphicsObject;
System.Drawing.Image imageObject = System.Drawing.Image.FromFile(Server.MapPath(@"Images\imageBack.jpg"));

// Create the Raster Image Object
raster = new Bitmap (imageObject);

//Create the Graphics Object
graphicsObject = Graphics.FromImage(raster);

//Instantiate object of brush with black color
SolidBrush imgBrush = new SolidBrush(Color.Black);

//Add the characters to the image
for (iIterate=0; iIterate {
imgFont = new Font("Arial", 20, FontStyle.Bold);
String str = imageText.Substring(iIterate, 1);
graphicsObject.DrawString(str, imgFont, imgBrush, iIterate * 20, 35);
graphicsObject.Flush();
}

// Generate a uniqiue file name to save image as
String fileName= new Random().Next().ToString() + ".gif";
raster.Save(Server.MapPath(fileName), System.Drawing.Imaging.ImageFormat.Gif);
raster.Dispose();
graphicsObject=null;

return fileName;

}
}

I just signed up at Server Intellect and couldn't be more pleased with my Windows Server! Check it out and see for yourself.

This final method is the crux of the example; this is where we do all of the graphic conversions and writing to the image that we are creating. In this example we are using a readable font for illustration purposes, you might want to change that font to a font that is harder to read to help protect your image from being read via OCR recognition.
We are also using a single background called “imageBack.jpg”, that can be found in the “Images” directory. You can create an array of images if you like and also randomly use those images so your image backgrounds can be different each time you retrieve one.
The last thing we do in this example is create the unique file name in the web service directory so we can pick up that file and turn it into a byte array. You need to do one of two things differently with this example in a production web service.

  • Clean up after yourself - You need to delete the image files that are being created in the web service directory after you have used them and sent them back to the client side application. We have not done that in this example because we wanted you to see the files themselves after they have been generated, and there is a possibility that you might want to create an archiving process that will store these images along with information about the date and time they were used.
  • You might want to consider taking the generation method code and generating it into a stream that is held in memory and never written to the hard drive. This way you do not have to clean up after yourself and it is a much cleaner way of dealing with the images.

You have now created the Captcha image web service and are ready to start receiving images back from this web service. In part two of this article we will run this web service and explain what the various inputs and outputs look like and how they work.
What we have Learned
 

Server Intellect offers Windows Hosting Dedicated Servers at affordable prices. I'm very pleased!

We have learned that we can easily create a web service that can be used on a local intranet system or can be publicly accessed via the internet, which will serve up Captcha images as requested. We also learned that when this web service is invoked it will return the byte array as designed and when that byte array is transformed in your client side code it will look like a normal Captcha image as seen.
Ideas for future enhancements:

  • Security
  • Encryption
  • Passing an object to the public method rather than a string
  • Using memory rather than a file to process the image

Attachments



Download Project Source - Enter your Email to be emailed a link to download the Full Source Project used in this Tutorial!



100% SPAM FREE! We will never sell or rent your email address!