The joy of working with the MVC framework is its total flexibility! See something that works great but could work better? Or perhaps you just need to add some custom functionality or features to the framework? No problem. In this case I am interested in creating an ActionResult that is capable of generating a CAPTCHA image as its result.
If you are not familiar with what CAPTCHA stands for or what it is used for take a quick look at this wiki post.
Before we can really look at the MVC framework and how to create a custom ActionResult that returns a CAPTCHA image, we first need create the code that generates a CAPTCA image. I have a class that does this for me (included in the download) which I will briefly cover.
How does CAPTCHA work?
The down and dirty idea of CAPTCHA is that you come up with a random number, word, or words. This generated text is then stored in the users session for matching against later. It is then distorted, tweaked, colorized, etc., and then rendered out to an image. The user takes a guess at what they see in the image and types it into a text box. This user submission is paired against what was originally stored in the session. If they match then the user is allowed to use the requested resource.
The CAPTCHA class that is provided
I have been using the same CAPTCHA class for quite some time now. Over time it has been tweaked a bit more but for the most part is the same.
- Generate the random text. This can be done with a word dictionary, a random string generator, or a random number generator. I have a method exposed off of my Captcha class called GenerateRandomCode which returns a random number.
- Create an instance of the Captcha class.
- Set the
Text property of the Captcha instance to the random text you created in step 1.
- Set the height and width of the image that you wish to be generated.
- Set the font family that you wish to use for your generated image.
- Use the generated Bitmap from the
Captcha.Image property in the most appropriate manner for your situation.
There are quite a few areas of the Captcha class that can also be exposed as properties such as the background color, hatching foreground and background colors, if a background image is to be used, etc. I will leave that up to you!
See the download for this code.
Creating the CAPTCHA ActionResult
Now that we have a functioning CAPTCHA class that will generate a CAPTCHA image for us, lets create the custom ActionResult which will return the CAPTCHA image for us.
Creating the CaptchaResult
The first step for us is to create a new ASP.NET MVC project. Mine is simply named MvcApplication1 – nothing special. From there I am going to place my Captcha class into the Models folder of my project. Then I am going to create a new CaptchaResult class. This class will inherit from ActionResult and therefore will need to implement the ExecuteResult method.
Listing 1: CaptchaResult.cs
Next we need to set up our CaptchaResult to accept a string into the constructor for our randomly generated code. I am choosing to set this up externally to the action (and the Captcha class) so that the user can specify the code and how they wish to store it for later use (session, etc.).
Listing 2: CaptchaResult.cs
From there we can create an instance of our Captcha class inside our
ExecuteResult method. We will set the text via the
_captchaText variable. Then we will set up the height and width of the image to be created as well as the font family that we will use.
With this data passed into our Captcha instance we can then look to saving the image into the response stream. To do that we have to clear the response. Then we will set the response type to "image/jpeg". And then we can finally save the Bitmap into the response stream.
Listing 3: CaptchaResult.cs
Now we can take a look at what it will take to use our new CaptchaResult.
Using our new CaptchaResult
In order to use our CaptchaResult we simply need to add it to one of our controllers. In this case we will add our new CaptchaResult to our HomeController class in the form of a GetCaptcha method. In this method we will need to get our generated text either from the GenerateRandomCode method in the Captcha class or from some other place (like a word dictionary). Then we will add the text to the user's session. And finally we will pass our generated text into our new CaptchaResult class which will generate the CAPTCHA image for us.
Listing 4: HomeController.cs
Once we have this new CaptchaResult in place we can test it by calling it from an image tag in the Index view for the home controller (recall that it is responsible for returning a jpeg image).
Listing 5: Index.aspx
Once you see your CAPTCHA output we can now work on implementing the capture part of the CAPTCHA. To do this all we need to do is add a form, a text box, the image, and a button.
Listing 6: Index.aspx
The output should now look like this.
Once we have the UI completed for our CAPTCHA we can now work on capturing the form submission. We will do this with a new Index action that accepts a form post.
Listing 7: HomeController.cs
As you can see we are simply capturing the users input with our
captcha method input. We then compare that users input with the value stored in the session. If the strings match we return a success message, otherwise we return a try again message. We then return the view.
In this article we took a quick look at what a CAPTCHA system would be used for. We also discussed the general process for creating a CAPTCHA. Next we discussed the Captcha class that I was going to use for this article. Then we implemented a custom ActionResult that returns the generated CAPTCHA image. With the custom CaptchaResult created we then looked at completing the implementation of our CAPTCHA systems UI by creating the view code and a new action in the home controller. Hopefully this article showed you not only how to create a CAPTCHA system but also how flexible the MVC framework is!
I am a 33 year old, ex-Army Ranger, father of 6, geeky software engineer that loves to code, teach, and write. In my spare time (ha!) I like playing with my 6 kids, horses, and various other animals.
This author has published 29 articles on DotNetSlackers. View other articles or the complete profile here.
Please login to rate or to leave a comment.