Portal
Language
 
Home>Knowledge Base>למתכנת>MVC3 simpel captcha and Invisible captcha
Information
Article ID46
Created On1/27/2012
Modified1/28/2012
MVC3 simpel captcha and Invisible captcha
http://mvc3captcha.codeplex.com

Example for mvc3 simple captcha and Invisible captcha.

Download and add model, controller and partial view.

Inside form add partial views.

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <div class="editor-label">
        @Html.LabelFor(model => model.Text)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Text)
        @Html.ValidationMessageFor(model => model.Text)
    </div>

    @Html.Partial("_Captcha", new Uco.Models.Captcha())
    @Html.Partial("_InvisibleCaptcha", new Uco.Models.InvisibleCaptcha())

    <p>
        <input type="submit" value="Send" />
    </p>
}

In controller check captcha:

 

[HttpPost]
public ActionResult Index(string CaptchaValue, string InvisibleCaptchaValue)
{
	bool cv = CaptchaController.IsValidCaptchaValue(CaptchaValue.ToUpper());
	bool icv = InvisibleCaptchaValue == "";

	if (!cv || !icv)
	{
		ModelState.AddModelError(string.Empty, "Captcha error.");
		return View();
	}

	if (ModelState.IsValid)
	{
		// do work

		return View();
	}
	else return View();
}




VIEW:

_Captcha.cshtml:
@model Uco.Models.Captcha
<img src='@Url.Content("~/Captcha/Show")' alt="" class="captcha_img" /> @Html.TextBoxFor(m => m.CaptchaValue, new { @class = "captcha_input" }) @Html.ValidationMessageFor(m => m.CaptchaValue)

_InvisibleCaptcha.cshtml:
@model Uco.Models.InvisibleCaptcha
<div style="display:none;">
    <div class="editor-label">
        @Html.LabelFor(model => model.CaptchaValue)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.CaptchaValue)
        @Html.ValidationMessageFor(model => model.CaptchaValue)
    </div>
</div>

MODEL
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Web.Mvc;
using System.ComponentModel;
using Uco.Infrastructure;

namespace Uco.Models
{
    public class Captcha
    {
        [Display(Name = "Captcha", Order = 20, ResourceType = typeof(Uco.Content.Resources.Models))]
        [Remote("ValidateCaptcha", "Captcha")]
        [Required()]
        public virtual string CaptchaValue { get; set; }
        public Captcha()
        {

        }
    }

    public class InvisibleCaptcha
    {
        [Display(Name = "InvisibleCaptcha", Order = 20, ResourceType = typeof(Uco.Content.Resources.Models))]
        [Remote("ValidateInvisibleCaptcha", "Captcha")]
        public virtual string CaptchaValue { get; set; }
        public InvisibleCaptcha()
        {

        }
    }
}


CONTROLLER:

using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Web.Mvc;

namespace Uco.Controllers
{
    public class CaptchaController : Controller
    {
        public JsonResult ValidateCaptcha(string CaptchaValue)
        {
            bool b = IsValidCaptchaValue(CaptchaValue.ToUpper());
            if (!b) return Json(string.Empty, JsonRequestBehavior.AllowGet);
            else return Json(true, JsonRequestBehavior.AllowGet);
        }
        public JsonResult ValidateInvisibleCaptcha(string CaptchaValue)
        {
            bool b = CaptchaValue == "";
            if (!b) return Json(string.Empty, JsonRequestBehavior.AllowGet);
            else return Json(true, JsonRequestBehavior.AllowGet);
        }

        private const int height = 30;
        private const int width = 80;
        private const int length = 4;
        private const string chars = "ABCDEFGHIJKLMNPQRSTUVWXYZ123456789";

        public ActionResult Show()
        {
            var randomText = GenerateRandomText(length);
            var hash = ComputeMd5Hash(randomText + GetSalt());
            Session["CaptchaHash"] = hash;

            var rnd = new Random();
            var fonts = new[] { "Verdana", "Times New Roman" };
            float orientationAngle = rnd.Next(0, 359);
            
            var index0 = rnd.Next(0, fonts.Length);
            var familyName = fonts[index0];

            using (var bmpOut = new Bitmap(width, height))
            {
                var g = Graphics.FromImage(bmpOut);
                var gradientBrush = new LinearGradientBrush(new Rectangle(0, 0, width, height),
                                                            Color.White, Color.DarkGray,
                                                            orientationAngle);
                g.FillRectangle(gradientBrush, 0, 0, width, height);
                DrawRandomLines(ref g, width, height);
                g.DrawString(randomText, new Font(familyName, 18), new SolidBrush(Color.Gray), 0, 2);
                var ms = new MemoryStream();
                bmpOut.Save(ms, ImageFormat.Png);
                var bmpBytes = ms.GetBuffer();
                bmpOut.Dispose();
                ms.Close();

                return new FileContentResult(bmpBytes, "image/png");
            }
        }

        public static bool IsValidCaptchaValue(string captchaValue)
        {
            var expectedHash = System.Web.HttpContext.Current.Session["CaptchaHash"];
            var toCheck = captchaValue + GetSalt();
            var hash = ComputeMd5Hash(toCheck);
            return hash.Equals(expectedHash);
        }

        private static void DrawRandomLines(ref Graphics g, int width, int height)
        {
            var rnd = new Random();
            var pen = new Pen(Color.Gray);
            for (var i = 0; i < 10; i++)
            {
                g.DrawLine(pen, rnd.Next(0, width), rnd.Next(0, height),
                                rnd.Next(0, width), rnd.Next(0, height));
            }
        }

        private static string GetSalt()
        {
            return typeof(CaptchaController).Assembly.FullName;
        }

        private static string ComputeMd5Hash(string input)
        {
            var encoding = new ASCIIEncoding();
            var bytes = encoding.GetBytes(input);
            HashAlgorithm md5Hasher = MD5.Create();
            return BitConverter.ToString(md5Hasher.ComputeHash(bytes));
        }

        private static string GenerateRandomText(int textLength)
        {
            var random = new Random();
            var result = new string(Enumerable.Repeat(chars, textLength)
                  .Select(s => s[random.Next(s.Length)]).ToArray());
            return result;
        }
    }
}