ASP.net 验证码(C#) MVC

http://blog.163.com/xu_shuhao/blog/static/5257748720101022697309/

网站添加验证码,主要为防止机器人程序批量注册,或对特定的注册用户用特定程序暴力破解方式,以进行不断的登录、灌水等危害网站的操作。验证码被广泛应用在注册、登录、留言等提交信息到服务器端处理的页面中。
     在ASP.NET网站中应用验证码是很容易的,网上有很多的解决方案。最近在做一个OA项目,因系统采用的ASP.NET MVC框架,同样在登录页中需用到验证码,故需将原来在ASP.NET网站中使用的验证码移植到ASP.NET MVC中。
     原ASP.NET网站用来生成验证码的类文件ValidateCode.cs:


using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Web.UI;
using System.Drawing.Drawing2D;
using System.IO;
namespace SeniOA.MVC
{
/// <summary>
/// 生成验证码的类
/// </summary>
public class ValidateCode
    {
public ValidateCode()
        {
        }
/// <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="containsPage">要输出到的page对象</param>
/// <param name="validateNum">验证码</param>
public void 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);
//输出图片流
                containsPage.Response.Clear();
                containsPage.Response.ContentType = "image/jpeg";
                containsPage.Response.BinaryWrite(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;
        }
    }
}

为适合ASP.NET MVC框架,修改其输出图片流的方法CreateValidateGraphic为:


/// <summary>
/// 创建验证码的图片
/// </summary>
/// <param name="containsPage">要输出到的page对象</param>
/// <param name="validateNum">验证码</param>
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();
    }
}

在Controller.cs中,添加Action,用来设置将生成的验证码存入Session,并输出验证码图片:


public ActionResult GetValidateCode()
{
    ValidateCode vCode = new ValidateCode();
string code = vCode.CreateValidateCode(5);
    Session["ValidateCode"] = code;
byte[] bytes = vCode.CreateValidateGraphic(code);
return File(bytes, @"image/jpeg");
}

调用方式为:在需要使用验证码的页面中,加入<img>标签:
<img id="valiCode" style="cursor: pointer;" src="../Account/GetValidateCode" alt="验证码" />
    效果如下图:

    到于Account/Login这个Action中的处理,只需加入对Session中验证码的判断:


[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Login(string userName, string password, bool rememberMe, string returnUrl,string code)
{
if (Session["ValidateCode"].ToString() != code)
    {
        ModelState.AddModelError("code", "validate code is error");
return View();
    }
//此处验证用户名、密码
if (!ValidateLogOn(userName, password))
    {
return View();
    }
//验证成功
    FormsAuthentication.SetAuthCookie(userName, rememberMe);
if (!String.IsNullOrEmpty(returnUrl))
    {
return Redirect(returnUrl);
    }
else
    {
return RedirectToAction("Index", "Home");
    }
}

为实现登录页中,点击图片切换验证码,可以登录页中加入此JS代码实现刷新验证码:


<script type="text/javascript" src="http://www.cnblogs.com/Scripts/jquery-1.3.2-vsdoc.js"></script>
<script type="text/javascript">
    $(function() {
    $("#valiCode").bind("click", function() {
this.src = "../Account/GetValidateCode?time=" + (new Date()).getTime();
        });
//alert("good");
    });
</script>

至此,ASP.NET MVC中已成功实现验证码功能。

最新文章

  1. xml序列化及反序列化.net对象
  2. Spring中属性文件properties的读取与使用
  3. JavaScript中经典方法
  4. ASP.NET中使用DropDownList实现无刷新二级联动详细过程
  5. Mac OS系统
  6. Hive QL 介绍
  7. spin_count
  8. 简单介绍如何使用robotium进行自动化测试
  9. 每天一个Linux命令(17)--whereis命令
  10. C#winform程序关闭计算机的正确姿势
  11. 芝麻HTTP:redis-py的安装
  12. python 迭代器 生成器
  13. 数据库查询优化——Mysql索引
  14. socket传输数据循环多次的性能要好于一次
  15. JS解决在提交form表单时某个值不存在 alter弹窗点确定不刷新界面
  16. Vue基础01vue的基本示例,vue的双向数据绑定,vue中常见的几种用法,vue相关常见指令
  17. Hadoop2源码分析-YARN RPC 示例介绍
  18. Vue项目
  19. Excel添加下拉菜单
  20. React 基础实例教程

热门文章

  1. Python的logger配制文件
  2. 【SoapUI】http接口测试
  3. .net 金额中文大写 日期转中文
  4. sublime开启vi编辑器功能,与vi常用快捷键
  5. C# 用tabcontrol实现窗体类似网页排版的显示
  6. tp3.2博客详情页面查询上一篇下一篇
  7. node的版本控制之nvm的安装与使用
  8. .NET开源工作流RoadFlow-表单设计-附件管理
  9. 仿照jQuery写一个关于选择器的框架(带了注释,请多多指教~)
  10. Object中的clone方法