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:
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.
In the View, beside a label, textbox and validator span you’ll need to add an image placeholder for the CAPTCHA.
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;
}
{
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;
}
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; }
}
{
//model specific fields [Required]
[Display(Name = "How much is")]
public string Captcha { get; set; }
}
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>
@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");
}
{
//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");
}
this is very useful and easy to implement! keep posting. Anti captcha key
ReplyDeleteTinted: Prices of Titanium Rocks - iTaniumArts
ReplyDeleteTinted: Prices of Titanium Rocks. Buy womens titanium wedding bands it titanium eyeglass frames online, buy it 출장안마 on the website. titanium welding Price is 0.10 EUR, 30 USD and other currencies are currencies everquest: titanium edition of the