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中已成功实现验证码功能。

ASP.net 验证码(C#) MVC的更多相关文章

  1. MVC的验证(模型注解和非侵入式脚本的结合使用) .Net中初探Redis .net通过代码发送邮件 Log4net (Log for .net) 使用GDI技术创建ASP.NET验证码 Razor模板引擎 (RazorEngine) .Net程序员应该掌握的正则表达式

    MVC的验证(模型注解和非侵入式脚本的结合使用)   @HtmlHrlper方式创建的标签,会自动生成一些属性,其中一些属性就是关于验证 如图示例: 模型注解 通过模型注解后,MVC的验证,包括前台客 ...

  2. [译]Introducing ASP.NET vNext and MVC 6

    原文:http://www.infoq.com/news/2014/05/ASP.NET-vNext?utm_source=tuicool Part of the ASP.NET vNext init ...

  3. 003. Asp.Net Routing与MVC 之一: 请求如何到达MVC

    基础知识 本文用到的基础知识:URL.HttpModule 与 HttpHandler.IIS 的请求处理过程. URL HttpModule与HttpHandler IIS7.0的请求处理过程 OK ...

  4. 解析ASP.NET WebForm和Mvc开发的区别

    因为以前主要是做WebFrom开发,对MVC开发并没有太深入的了解.自从来到创新工场的新团队后,用的技术都是自己以前没有接触过的,比如:MVC 和EF还有就是WCF,压力一直很大.在很多问题都是不清楚 ...

  5. Introducing ASP.NET vNext and MVC 6

    [译]Introducing ASP.NET vNext and MVC 6 原文:http://www.infoq.com/news/2014/05/ASP.NET-vNext?utm_source ...

  6. 005. Asp.Net Routing与MVC 之三: 路由在MVC的使用

    上次讲到请求如何激活Controller和Action,这次讲下MVC中路由的使用.本次两个关注点: 遗留:ModelBinder.BindModel的过程 MVC中路由的使用 MVC 5中的Acti ...

  7. 解析ASP.NET WebForm和Mvc开发的区别 分类: ASP.NET 2013-12-29 01:59 11738人阅读 评论(5) 收藏

    因为以前主要是做WebFrom开发,对MVC开发并没有太深入的了解.自从来到创新工场的新团队后,用的技术都是自己以前没有接触过的,比如:MVC 和EF还有就是WCF,压力一直很大.在很多问题都是不清楚 ...

  8. Log4Net 在ASP.NET WebForm 和 MVC的全局配置

    使用log4net可以很方便地为应用添加日志功能.应用Log4net,开发者可以很精确地控制日志信息的输出,减少了多余信息,提高了日志记录性能.同时,通过外部配置文件,用户可以不用重新编译程序就能改变 ...

  9. ASP.NET Core 配置 MVC - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 配置 MVC - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 配置 MVC 前面几章节中,我们都是基于 ASP.NET 空项目 ...

随机推荐

  1. 手机如何解散QQ讨论组

    手机如何解散QQ讨论组   讨论组可以方便一群人的聊天,一般都是一段时间的问题.过了这一段时间,大家都是不需要再在讨论组里面发言了,那么手机如何解散QQ讨论组呢?     1 我们登录自己的 QQ之后 ...

  2. JS获取URL中参数值(QueryString)的4种方法分享<转>

    方法一:正则法 复制代码代码如下: function getQueryString(name) {    var reg = new RegExp('(^|&)' + name + '=([^ ...

  3. (转)接口自动化测试 – Java+TestNG 测试 Restful Web Service

    本文主要介绍如何用Java针对Restful web service 做接口自动化测试(数据驱动),相比UI自动化,接口自动化稳定性可靠性高,实施难易程度低,做自动化性价比高.所用到的工具或类库有 T ...

  4. django的安装和搭建

    一.先下载pyton,配置下python的环境变量,这个很重要,然后下载django,解压到与python同一个根目录底下,进入django目录,运行python setup.py install安装 ...

  5. Python学习笔记7—集合

    set 拥有类似 dict 的特点:可以用{}花括号来定义:其中的元素没有序列,也就是是非序列类型的数据;而且,set 中的元素不可重复,这就类似 dict 的键. >>> s1 = ...

  6. POJ 2385 Apple Catching

    比起之前一直在刷的背包题,这道题可以算是最纯粹的dp了,写下简单题解. 题意是说cows在1树和2树下来回移动取苹果,有移动次数限制,问最后能拿到的最多苹果数,含有最优子结构性质,大致的状态转移也不难 ...

  7. webpages框架中使用Html.TextArea()在前台显示多行信息时,如何进行大小、样式的设置

    环境:vs2015 webpages框架+razor语法: 目的:服务器进行数据更新操作后,在前台显示更新的相关信息: 后台代码:将更新条数等相关信息存储在一个变量中: @{ var serverIn ...

  8. 【转】 Live555

    Ⅰ live555简介 Live555 是一个为流媒体提供解决方案的跨平台的C++开源项目,它实现了对标准流媒体传输协议如RTP/RTCP.RTSP.SIP等的支持.Live555实现了对多种音视频编 ...

  9. 简单的css居中问题(日常记录)

    1.今天遇到了一个奇怪的问题:因为网页要适配大小分辨屏幕,需要把一张图片放到div中,我的初始思路是把图放在div中绝对对位给top50%left50%,但是不行,因为当网页调窄时图片就因为显得太大了 ...

  10. 【bzoj1059】矩形游戏

    题意 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏--矩阵游戏.矩阵游戏在一个N*N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种操作:行交换操作 ...