ASP.net 验证码(C#) MVC
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的更多相关文章
- MVC的验证(模型注解和非侵入式脚本的结合使用) .Net中初探Redis .net通过代码发送邮件 Log4net (Log for .net) 使用GDI技术创建ASP.NET验证码 Razor模板引擎 (RazorEngine) .Net程序员应该掌握的正则表达式
MVC的验证(模型注解和非侵入式脚本的结合使用) @HtmlHrlper方式创建的标签,会自动生成一些属性,其中一些属性就是关于验证 如图示例: 模型注解 通过模型注解后,MVC的验证,包括前台客 ...
- [译]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 ...
- 003. Asp.Net Routing与MVC 之一: 请求如何到达MVC
基础知识 本文用到的基础知识:URL.HttpModule 与 HttpHandler.IIS 的请求处理过程. URL HttpModule与HttpHandler IIS7.0的请求处理过程 OK ...
- 解析ASP.NET WebForm和Mvc开发的区别
因为以前主要是做WebFrom开发,对MVC开发并没有太深入的了解.自从来到创新工场的新团队后,用的技术都是自己以前没有接触过的,比如:MVC 和EF还有就是WCF,压力一直很大.在很多问题都是不清楚 ...
- 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 ...
- 005. Asp.Net Routing与MVC 之三: 路由在MVC的使用
上次讲到请求如何激活Controller和Action,这次讲下MVC中路由的使用.本次两个关注点: 遗留:ModelBinder.BindModel的过程 MVC中路由的使用 MVC 5中的Acti ...
- 解析ASP.NET WebForm和Mvc开发的区别 分类: ASP.NET 2013-12-29 01:59 11738人阅读 评论(5) 收藏
因为以前主要是做WebFrom开发,对MVC开发并没有太深入的了解.自从来到创新工场的新团队后,用的技术都是自己以前没有接触过的,比如:MVC 和EF还有就是WCF,压力一直很大.在很多问题都是不清楚 ...
- Log4Net 在ASP.NET WebForm 和 MVC的全局配置
使用log4net可以很方便地为应用添加日志功能.应用Log4net,开发者可以很精确地控制日志信息的输出,减少了多余信息,提高了日志记录性能.同时,通过外部配置文件,用户可以不用重新编译程序就能改变 ...
- ASP.NET Core 配置 MVC - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core 配置 MVC - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 配置 MVC 前面几章节中,我们都是基于 ASP.NET 空项目 ...
随机推荐
- Java中List Set Map 是否有序等总结
1.Collection List Set Map 区别记忆 这些都代表了Java中的集合,这里主要从其元素是否有序,是否可重复来进行区别记忆,以便恰当地使用,当然还存在同步方面的差异,见上一篇相关文 ...
- Linux系统负载排查
参考 http://www.ruanyifeng.com/blog/2011/07/linux_load_average_explained.html 在Linux系统中,我们一般使用uptime命 ...
- RAC 集群更换IP
RAC 集群更换 IP 主要分三步:停集群服务.配置服务器网络.修改集群配置.下面是同网段内更换 IP 示例.(r7.r8为服务器名称,orcl为ORACLE_SID,scanip为 scan 名称) ...
- vim 空格和换行的删除和替换
%s/\s//g %s/\r//g %s/\n//g 把一个很长的一行按空格分为多行 :%s/ +/\r/g简单解释一下:%s :在整个文件范围查找替换/ :分隔符+ :匹配空格,其中“ ”表 ...
- phalcon: queueing使用心得,需要安装相应的软体
http://flyhighest.com/archives/50 原本没有用过phalcon的消息队列,本来以为很简单,结果搞了半天,把步骤记录一下. phalcon的官网上没有说需要安装beans ...
- 与MySQL的零距离接触 - 慕课网
课程链接:与MySQL的零距离接触 环境配置: windows下安装mysql Download MySQL Installer for windows 课程目录 第1章 初涉MySQL 1- ...
- 获取AVCaptureSession samplebuffer 一像素的 rgb值
获取AVCaptureSession samplebuffer 一像素的 rgb值 typedef unsigned char byte; typedef struct RGBPixel{ byte ...
- zju 1091
// Traveling Knight Problem #include "stdafx.h" #include <string> #include <strin ...
- win7开启硬盘AHCI
问题描述:装win7的时候没有在AHCI模式下安装,而是在IDE模式下安装的,后来安装完毕以后想更改成AHCI模式,可是更改以后启动电脑蓝屏并重启 解决方法: 如果是在IDE模式下安装的系统,由于在安 ...
- 初学java之异常类
//异常类 package st; public class example_1 { public static void main(String args[]) { int n=0,m=0,t=10 ...