zoukankan      html  css  js  c++  java
  • MVC中验证码

    MVC中验证码的实现(经常用,记录备用)

     

    一、目录

     1、多层架构+MVC+EF+AUTOFAC+AUTOMAPPER;

     2、MVC中验证码的实现(经常用,记录备用)

     3、Ligerui首页的快速搭建。

    二 正文

     Ok,我们的验证码开始,这篇文章不写怎么生成验证码,意在将MVC下几个验证码方法贴出来,大家以后需要的时候直接调用就行了。

     

     我们的框架中有上图这么一个类,里面有生成验证码的两个方法,位于框架中的基础设施层当中:

      

     ValidatorCodeTools

    namespace YTJWGL_Common
    {
    public class ValidatorCodeTools
    {
    #region 生成校验码图片
    public ValidatorCodeTools()
    {
    }
    /// <summary>
    /// 验证码的最大长度
    /// </summary>
    public int MaxLength
    {
    get { return 10; }
    }
    /// <summary>
    /// 验证码的最小长度
    /// </summary>
    public int MinLength
    {
    get { return 1; }
    }
    /// <summary>
    /// 生成验证码
    /// </summary>
    /// <param name="length">指定验证码的长度</param>
    /// <returns></returns>
    public string CreateValidateCode(int length)
    {
    int[] randMembers = new int[length];
    int[] validateNums = new int[length];
    string validateNumberStr = "";
    //生成起始序列值
    int seekSeek = unchecked((int)DateTime.Now.Ticks);
    Random seekRand = new Random(seekSeek);
    int beginSeek = (int)seekRand.Next(0, Int32.MaxValue - length * 10000);
    int[] seeks = new int[length];
    for (int i = 0; i < length; i++)
    {
    beginSeek += 10000;
    seeks[i] = beginSeek;
    }
    //生成随机数字
    for (int i = 0; i < length; i++)
    {
    Random rand = new Random(seeks[i]);
    int pownum = 1 * (int)Math.Pow(10, length);
    randMembers[i] = rand.Next(pownum, Int32.MaxValue);
    }
    //抽取随机数字
    for (int i = 0; i < length; i++)
    {
    string numStr = randMembers[i].ToString();
    int numLength = numStr.Length;
    Random rand = new Random();
    int numPosition = rand.Next(0, numLength - 1);
    validateNums[i] = Int32.Parse(numStr.Substring(numPosition, 1));
    }
    //生成验证码
    for (int i = 0; i < length; i++)
    {
    validateNumberStr += validateNums[i].ToString();
    }
    return validateNumberStr;
    }
    /// <summary>
    /// 创建验证码的图片
    /// </summary>
    /// <param name="validateCode">验证码内容</param>
    /// <returns></returns>
    public byte[] CreateValidateGraphic(string validateCode)
    {
    Bitmap image = new Bitmap((int)Math.Ceiling(validateCode.Length * 12.0), 22);
    Graphics g = Graphics.FromImage(image);
    try
    {
    //生成随机生成器
    Random random = new Random();
    //清空图片背景色
    g.Clear(Color.White);
    //画图片的干扰线
    for (int i = 0; i < 25; i++)
    {
    int x1 = random.Next(image.Width);
    int x2 = random.Next(image.Width);
    int y1 = random.Next(image.Height);
    int y2 = random.Next(image.Height);
    g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
    }
    Font font = new Font("Arial", 12, (FontStyle.Bold | FontStyle.Italic));
    LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height),
    Color.Blue, Color.DarkRed, 1.2f, true);
    g.DrawString(validateCode, font, brush, 3, 2);
    //画图片的前景干扰点
    for (int i = 0; i < 100; i++)
    {
    int x = random.Next(image.Width);
    int y = random.Next(image.Height);
    image.SetPixel(x, y, Color.FromArgb(random.Next()));
    }
    //画图片的边框线
    g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
    //保存图片数据
    MemoryStream stream = new MemoryStream();
    image.Save(stream, ImageFormat.Jpeg);
    //输出图片流
    return stream.ToArray();
    }
    finally
    {
    g.Dispose();
    image.Dispose();
    }
    }
    /// <summary>
    /// 得到验证码图片的长度
    /// </summary>
    /// <param name="validateNumLength">验证码的长度</param>
    /// <returns></returns>
    public static int GetImageWidth(int validateNumLength)
    {
    return (int)(validateNumLength * 12.0);
    }
    /// <summary>
    /// 得到验证码的高度
    /// </summary>
    /// <returns></returns>
    public static double GetImageHeight()
    {
    return 22.5;
    }
    #endregion
    }
    }

    ValidatorCodeTools

     CreateValidateCode方法生成验证码内容,对应图片中的形如“54361”这样的数字。而CreateValidateGraphic该方法接收一个参数,把参数中的验证码转换为图片显示。

     接下来,在BLL层有两个方法:

     AdminService

    namespace YTJWGL_Bll
    {
    public class AdminService : BaseService<YTJWGL_Admin>, IAdminService
    {

    /// <summary>
    /// 生成验证码数字
    /// </summary>
    /// <param name="id">验证码位数,默认为5</param>
    /// <returns></returns>
    public string NewValidateCode(int id = 5)
    {
    ValidatorCodeTools obj = new ValidatorCodeTools();
    return obj.CreateValidateCode(5);
    }
    /// <summary>
    /// 验证码图片
    /// </summary>
    /// <param name="code"></param>
    /// <returns></returns>
    public byte[] NewValidateCodeGraphic(string code)
    {
    ValidatorCodeTools obj = new ValidatorCodeTools();
    return obj.CreateValidateGraphic(code);
    }
    }
    }

    AdminService

     没什么好稀奇,就是调用基础设施层的两个方法。

     到这,我们的菜的“调料”已经备齐,下一步就是“炒菜”了。

     在你自己认为合适的控制器中新建一个Action:

     GetValidatorGraphics

      在Action中调用我们刚才在BLL层定义的两个方法,返回这张验证码图片。因为http是无连接的,这个action仅仅响应用户一次访问请求,当用户点击登录后会将填写的验证码发送到服务器,而这已经是第二次访问请求了,所以需要用Session用来保存刚才发往客户端的验证码。

      那么,怎么在界面上请求这张验证码图片呢?

     

    namespace YTJWGL_WebUI.Areas.Admin.Controllers
    {

    public class FrameController : Controller
    {
    //
    // GET: /Admin/Frame/
    #region Fields

    private readonly IAdminService _adminService;
    private readonly IAdminAuthorityService _adminAuthorityService;
    private readonly IAdminRoleService _adminRoleService;
    private readonly ILogService _logService;


    #endregion

    #region Constructors

    public FrameController(IAdminService adminService, IAdminAuthorityService adminAuthorityService, IAdminRoleService adminRoleService, ILogService logService)
    {
    this._adminService = adminService;
    this._adminAuthorityService = adminAuthorityService;
    this._adminRoleService = adminRoleService;
    this._logService = logService;
    }
    #endregion

    #region Admin

    public ActionResult GetValidatorGraphics()
    {
    string code = _adminService.NewValidateCode();
    Session["ValidatorCode"] = code;
    byte[] graphic = _adminService.NewValidateCodeGraphic(code);
    return File(graphic, @"image/jpeg");
    }
    #endregion
    }
    }

    GetValidatorGraphics

      相当简单,只需要使用<img>标签的src属性访问我们刚才的action。

      生成的效果在这:

      

      对于有特殊样式需求的验证码,基础层中的两个方法需要重写,但是大部分情形下,这样的效果已经能满足需求了。

      到了最后一步喽:点击图片,刷新我们验证码图片中的数字,这个必须的,也很Easy。

      

     JS

    <script type="text/javascript">
    //当点击图片时,刷新验证码
    $(function () {
    $("#valiCode").bind("click", function () {
    this.src = "@Url.Action("GetValidatorGraphics", "Frame")?time=" + (new Date()).getTime();
    });
    });
    </script>

    JS

      给img标签添加click事件,点击过后重新访问生成验证码的action,由于验证中数字是随机生成的,新返回的验证码图片就不一样了。避免浏览器缓存影响,src链接附件了一个随机时间。

      有需要的同学们copy CreateValidateCode,CreateValidateGraphic ……

      

      下一篇,我们搭建Ligerui 的官网首页:http://www.ligerui.com/

  • 相关阅读:
    LeetCode15 3Sum
    LeetCode10 Regular Expression Matching
    LeetCode20 Valid Parentheses
    LeetCode21 Merge Two Sorted Lists
    LeetCode13 Roman to Integer
    LeetCode12 Integer to Roman
    LeetCode11 Container With Most Water
    LeetCode19 Remove Nth Node From End of List
    LeetCode14 Longest Common Prefix
    LeetCode9 Palindrome Number
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3451858.html
Copyright © 2011-2022 走看看