• [翻译]ASP.NET MVC 3 开发的20个秘诀(十五)[20 Recipes for Programming MVC 3]:启用图片验证码(CAPTCHA)


    议题

    很多自动程序会自动提交表单,在互联网上造成大量的垃圾数据,为了防止这种情况发生,我们实现了图形验证码(CAPTCHACompletely Automated Public Turing test to tell Computers and Humans Apart),当用户提交时必须要在文本框中输入图片上显示的正确的字符。

     

    解决方案

    BookCommentsControllor控制器中安装ASP.NET Web Helper LibraryNuGet提供的CAPTCHA

     

    讨论

    包含一个新的Library Package,在窗体上添加一个CAPTCHAMicrosoftNuGet Web Helpers Library中内置CAPTCHA类,可以让我们很容易的实现验证用户输入的CAPTCHA

     

    Visual StudioMVC应用程序项目中,点击菜单“工具”→“Library Package Manager”→“Add Library Package Reference”。载入后,在左侧选择“Online”分类,在首页中选择“microsoft-web-helpers”,如果它不在列表里面,请在右上角搜索。找到后,点击“Install”。

     

    最典型的提交表单的案例就是提交评论。在之前的配方中,添加书籍评论就是添加CAPTCHA的完美事例。在开始之前,你需要将域名注册到RECAPTCHA网站。完成注册后,将会收到你网站专用的私钥和公钥。将它们复制保存以备将来使用。

     

    设置完成后,开始修改代码。在BookComments/Index视图中做一个小修改即可。这是之前创建的添加评论的页面,在发起Ajax请求时,显示CAPTCHA按钮,并在请求完成时调用名为“DisplayCaptcha”的Javascript方法。

    @model IEnumerable<MvcApplication4.Models.BookComment>
    @{
    ViewBag.Title = "Index";
    }
    <h2>Index</h2>
    <p>
    @Ajax.ActionLink("Create New", "Create", new {
    BookId = ViewBag.BookId },
    new AjaxOptions { UpdateTargetId = "AddComment",
    OnComplete = "DisplayCaptcha" })
    </p>
    <div id="AddComment"></div>
    ...
    <script type="text/javascript" src=
    "http://www.google.com/recaptcha/api/js/recaptcha_ajax.js"
    >
    </script>
    <script type="text/javascript">
    function DisplayCaptcha() {
    Recaptcha.destroy();
    Recaptcha.create(
    "<your_public_key>", "captcha", {});
    }

    </script>

    现在对BookComments/Create视图做一个小修改。首先,需要创建一个区域显示CAPTCHA和一个新的HTML标记,在用户输入错误的时候显示错误信息。最后,修改一下ReloadComment方法,在没有自动重新载入的情况下显示CAPTCHA(仅当没有出错时)。

    @model MvcApplication4.Models.BookComment
    @{
    ViewBag.Title = "Create";
    }
    <h2>Create</h2>
    @section JavascriptAndCSS {
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")"
    type
    ="text/javascript"></script>
    <script src="
    @Url.Content("
    ~/Scripts/jquery.validate.unobtrusive.min.js")"
    type
    ="text/javascript"></script>
    }
    <script type="text/javascript">
    function ReloadComments() {
    var reload = "@ViewBag.RefreshComments";
    if (reload == "False") {
    DisplayCaptcha();
    }
    else {
    $(
    "#Comments").load(
    "/BookComments/Index?BookId=@ViewBag.BookId");
    }
    }
    </script>
    @using (Ajax.BeginForm(new AjaxOptions {
    UpdateTargetId="AddComment", OnComplete="ReloadComments" }))
    {
    @Html.Hidden("BookId", (int)ViewBag.BookId);
    @Html.ValidationSummary(true)
    <fieldset>
    <legend>BookComment</legend>
    <div class="editor-label">
    @Html.LabelFor(model => model.Comment)
    </div>
    <div class="editor-field">
    @Html.TextAreaFor(model => model.Comment)
    @Html.ValidationMessageFor(model => model.Comment)
    </div>
    <div class="editor-label">
    Are you human?
    </div>
    <div class="editor-field">
    <div id="captcha"></div>
    @Html.ValidationMessage("Captcha")
    </div>
    <p>
    <input type="submit" value="Create" />
    </p>
    </fieldset>

    }

    最后,需要修改BookCommentsController验证用户输入的CAPTCHA。假如验证不成功,将错误信息添加到ModelState中,返回到视图中显示。

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Entity;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using MvcApplication4.Models;
    using Microsoft.Web.Helpers;

    namespace MvcApplication4.Controllers
    {
    public class BookCommentsController : Controller
    {
    private BookDBContext db = new BookDBContext();

    //
    // GET: /BookComments/
    public ActionResult Index(int BookId)
    {
    ViewBag.BookId = BookId;
    var bookcomments = db.BookComments.Include(
    b => b.Book).Where(b => b.BookId == BookId);
    return PartialView(bookcomments.ToList());
    }

    //
    // GET: /BookComments/Create
    public ActionResult Create(int BookId)
    {
    ViewBag.BookId = BookId;
    ViewBag.RefreshComments = false;
    return PartialView();
    }

    //
    // POST: /BookComments/Create
    [HttpPost]
    public ActionResult Create(BookComment bookcomment)
    {
    ViewBag.RefreshComments = false;
    var captchaSuccess = ReCaptcha.Validate(
    "<your_private_key>");
    if (ModelState.IsValid && captchaSuccess)
    {
    bookcomment.Created = DateTime.Now;
    db.BookComments.Add(bookcomment);
    db.SaveChanges();
    ViewBag.RefreshComments = true;
    }

    // if captcha failed add error message
    if (!captchaSuccess)
    {
    ModelState.AddModelError("Captcha",
    "Invalid CAPTCHA");
    }
    ViewBag.BookId = bookcomment.BookId;
    return PartialView(bookcomment);
    }

    protected override void Dispose(bool disposing)
    {
    db.Dispose();
    base.Dispose(disposing);
    }
    }
    }

    参考

    原书地址 书籍源代码

  • 相关阅读:
    Active Report 3 生成图表
    js asp.net enable/disable validator
    [.net] 如何在mail的加入正文显示图片
    [javascript] 得到 javascript 的当前文件名
    Colorful Stones
    Jam的计数法

    Beautiful Matrix
    能量项链
    Maxim and Discounts
  • 原文地址:https://www.cnblogs.com/o2ds/p/2292884.html
Copyright © 2020-2023  润新知