Tuesday, January 31, 2012

User friendly CAPTCHA for Asp.Net MVC


In this post I will show you how to add CAPTCHA functionality to a html form in an Asp.Net MVC 4 project. My goal is to make the CAPTCHA problem easy enough for all to solve, like a simple sum operation, and easier to read then the standard CAPTCHA text. An easy to read image is more vulnerable to smart bots that have an ORC system but I prefer to scare less clients then to provide the strongest anti-bot protection. And one more feature, when clicked the image should, change giving the users a new chance to respond correctly.

Implementing CAPTCHA in C# and MVC 4 takes these steps:
  • Create an Action that returns a CAPTCHA image and stores in the user session the right answer
  • Add to your Model a string property named Captcha
  • Add to your View the textbox for Captcha and the image placeholder
  • Validate answer inside your own Action

Render CAPTCHA image
CaptchaController.cs
        public ActionResult CaptchaImage(string prefix, bool noisy = true)
        {
            var rand = new Random((int)DateTime.Now.Ticks);
            //generate new question
            int a = rand.Next(10, 99);
            int b = rand.Next(0, 9);
            var captcha = string.Format("{0} + {1} = ?", a, b);
            //store answer
            Session["Captcha" + prefix] = a + b;
            //image stream
            FileContentResult img = null;
            using (var mem = new MemoryStream())
            using (var bmp = new Bitmap(130, 30))
            using (var gfx = Graphics.FromImage((Image)bmp))
            {
                gfx.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
                gfx.SmoothingMode = SmoothingMode.AntiAlias;
                gfx.FillRectangle(Brushes.White, new Rectangle(0, 0, bmp.Width, bmp.Height));
                //add noise
                if (noisy)
                {
                    int i, r, x, y;
                    var pen = new Pen(Color.Yellow);
                    for (i = 1; i < 10; i++)
                    {
                        pen.Color = Color.FromArgb(
                        (rand.Next(0, 255)),
                        (rand.Next(0, 255)),
                        (rand.Next(0, 255)));
                        r = rand.Next(0, (130 / 3));
                        x = rand.Next(0, 130);
                        y = rand.Next(0, 30);
                        gfx.DrawEllipse(pen, x – r, y – r, r, r);
                    }
                }
                //add question
                gfx.DrawString(captcha, new Font("Tahoma", 15), Brushes.Gray, 2, 3);
                //render as Jpeg
                bmp.Save(mem, System.Drawing.Imaging.ImageFormat.Jpeg);
                img = this.File(mem.GetBuffer(), "image/Jpeg");
            }
            return img;
        }
If you want to use multiple  CAPTCHAs you can use the prefix to store the answer for each form. Much can be improved regarding the rendered image, for example I could use different font and size for each number in the equation, replace the noise with text distortion.
Include  CAPTCHA validator in Model and View
Models.cs
    public class SubscribeModel
    {
        //model specific fields
        [Required]
        [Display(Name = "How much is")]
        public string Captcha { get; set; }
    }
In the View, beside a label, textbox and validator span you’ll need to add an image placeholder for the CAPTCHA.
Index.cshtml
@*form specific fields*@
<div class="editor-label">
    @Html.LabelFor(model => model.Captcha)
    <a href="@Url.Action("Index")">
        <img alt="Captcha" src="@Url.Action("CaptchaImage")" style="" />
    </a>
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Captcha)
    @Html.ValidationMessageFor(model => model.Captcha)
</div>
Validate CAPTCHA on the server side
Inside your post action where the form submits you can validate the answer by comparing with the session value.
CaptchaController.cs
[HttpPost]
public ActionResult Index(SubscribeModel model)
{
    //validate captcha
    if (Session["Captcha"] == null || Session["Captcha"].ToString() != model.Captcha)
    {
        ModelState.AddModelError("Captcha", "Wrong value of sum, please try again.");
        //dispay error and generate a new captcha
        return View(model);
    }
    return RedirectToAction("ThankYouPage");
}
Instead of validating the CAPTCHA on post, you can use an Ajax call to validate and refresh the image asynchronous, more details on how you can send forms data over Ajax read this blog post.
Prerequisites & Download
In order to easily install all the prerequisites you can use the Web Platform Installer version 4.
download source code files

Wednesday, January 18, 2012

Microsoft Codename Cloud Numerics

Microsoft Codename “Cloud Numerics” is a new .NET programming framework which can be used to perform intensive numeric computations on large distributed data sets. If you are some one who works with large data sets, extracting the data and forming and simulating the models then you might need more computing power and memory.
image

What to do? Is cloud is the option?? Is that possible to analyze the data and message computing using Cloud? There is a solution with Microsoft Codename “Cloud Numerics” it is easy to write models and applications and can handle the large datasets. You can use visual studio to write these types of applications.
image
Create a project of type Cloud Numerics Application in Visual Studio. You immediately have a access to an extensive set of numericals functions ranging from basic mathematics to statistics and algebra.
image  
All the complex numerical analysis can be done with .NET Cloud Numerics programming framework. All you need to do is make sure that your large data set defined as distributed array.
image
After that you just need to apply mean and Matrixmultiply operations
image
You can develop your model or application on your desktop using small data set. When you ready to scale out your application to cloud simply change your small data set reference in your code to large data set.
image
Now you can use the Cloud Numerics deployment wizard for deployment to the cloud.
image
Now you are running your big analytics on cloud. Cloud managed to provide ability to run complex data models on cloud. This enables you to process and analysis much larger datasets.
image
More about cloud numerics can be read here

Find a cool free stuff everyday

Giveaway of the Day

Hiren Bharadwa's Posts

DotNetJalps