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

一、目录

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

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

 3、Ligerui首页的快速搭建

二 正文

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

 

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

  

  1 namespace YTJWGL_Common
  2 {
  3     public class ValidatorCodeTools
  4     {
  5         #region 生成校验码图片
  6         public ValidatorCodeTools()
  7         {
  8         }
  9         /// <summary>
 10         /// 验证码的最大长度
 11         /// </summary>
 12         public int MaxLength
 13         {
 14             get { return 10; }
 15         }
 16         /// <summary>
 17         /// 验证码的最小长度
 18         /// </summary>
 19         public int MinLength
 20         {
 21             get { return 1; }
 22         }
 23         /// <summary>
 24         /// 生成验证码
 25         /// </summary>
 26         /// <param name="length">指定验证码的长度</param>
 27         /// <returns></returns>
 28         public string CreateValidateCode(int length)
 29         {
 30             int[] randMembers = new int[length];
 31             int[] validateNums = new int[length];
 32             string validateNumberStr = "";
 33             //生成起始序列值
 34             int seekSeek = unchecked((int)DateTime.Now.Ticks);
 35             Random seekRand = new Random(seekSeek);
 36             int beginSeek = (int)seekRand.Next(0, Int32.MaxValue - length * 10000);
 37             int[] seeks = new int[length];
 38             for (int i = 0; i < length; i++)
 39             {
 40                 beginSeek += 10000;
 41                 seeks[i] = beginSeek;
 42             }
 43             //生成随机数字
 44             for (int i = 0; i < length; i++)
 45             {
 46                 Random rand = new Random(seeks[i]);
 47                 int pownum = 1 * (int)Math.Pow(10, length);
 48                 randMembers[i] = rand.Next(pownum, Int32.MaxValue);
 49             }
 50             //抽取随机数字
 51             for (int i = 0; i < length; i++)
 52             {
 53                 string numStr = randMembers[i].ToString();
 54                 int numLength = numStr.Length;
 55                 Random rand = new Random();
 56                 int numPosition = rand.Next(0, numLength - 1);
 57                 validateNums[i] = Int32.Parse(numStr.Substring(numPosition, 1));
 58             }
 59             //生成验证码
 60             for (int i = 0; i < length; i++)
 61             {
 62                 validateNumberStr += validateNums[i].ToString();
 63             }
 64             return validateNumberStr;
 65         }
 66         /// <summary>
 67         /// 创建验证码的图片
 68         /// </summary>
 69         /// <param name="validateCode">验证码内容</param>
 70         /// <returns></returns>
 71         public byte[] CreateValidateGraphic(string validateCode)
 72         {
 73             Bitmap image = new Bitmap((int)Math.Ceiling(validateCode.Length * 12.0), 22);
 74             Graphics g = Graphics.FromImage(image);
 75             try
 76             {
 77                 //生成随机生成器
 78                 Random random = new Random();
 79                 //清空图片背景色
 80                 g.Clear(Color.White);
 81                 //画图片的干扰线
 82                 for (int i = 0; i < 25; i++)
 83                 {
 84                     int x1 = random.Next(image.Width);
 85                     int x2 = random.Next(image.Width);
 86                     int y1 = random.Next(image.Height);
 87                     int y2 = random.Next(image.Height);
 88                     g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
 89                 }
 90                 Font font = new Font("Arial", 12, (FontStyle.Bold | FontStyle.Italic));
 91                 LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height),
 92                  Color.Blue, Color.DarkRed, 1.2f, true);
 93                 g.DrawString(validateCode, font, brush, 3, 2);
 94                 //画图片的前景干扰点
 95                 for (int i = 0; i < 100; i++)
 96                 {
 97                     int x = random.Next(image.Width);
 98                     int y = random.Next(image.Height);
 99                     image.SetPixel(x, y, Color.FromArgb(random.Next()));
100                 }
101                 //画图片的边框线
102                 g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
103                 //保存图片数据
104                 MemoryStream stream = new MemoryStream();
105                 image.Save(stream, ImageFormat.Jpeg);
106                 //输出图片流
107                 return stream.ToArray();
108             }
109             finally
110             {
111                 g.Dispose();
112                 image.Dispose();
113             }
114         }
115         /// <summary>
116         /// 得到验证码图片的长度
117         /// </summary>
118         /// <param name="validateNumLength">验证码的长度</param>
119         /// <returns></returns>
120         public static int GetImageWidth(int validateNumLength)
121         {
122             return (int)(validateNumLength * 12.0);
123         }
124         /// <summary>
125         /// 得到验证码的高度
126         /// </summary>
127         /// <returns></returns>
128         public static double GetImageHeight()
129         {
130             return 22.5;
131         }
132         #endregion
133     }
134 }
ValidatorCodeTools

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

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

 1 namespace YTJWGL_Bll
 2 {
 3     public class AdminService : BaseService<YTJWGL_Admin>, IAdminService
 4     {
 5       
 6 
 7         /// <summary>
 8         /// 生成验证码数字
 9         /// </summary>
10         /// <param name="id">验证码位数,默认为5</param>
11         /// <returns></returns>
12         public string NewValidateCode(int id = 5)
13         {
14             ValidatorCodeTools obj = new ValidatorCodeTools();
15             return obj.CreateValidateCode(5);
16         }
17         /// <summary>
18         /// 验证码图片
19         /// </summary>
20         /// <param name="code"></param>
21         /// <returns></returns>
22         public byte[] NewValidateCodeGraphic(string code)
23         {
24             ValidatorCodeTools obj = new ValidatorCodeTools();
25             return obj.CreateValidateGraphic(code);
26         }
27     }
28 }
AdminService

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

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

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

 1 namespace YTJWGL_WebUI.Areas.Admin.Controllers
 2 {
 3     
 4     public class FrameController : Controller
 5     {
 6         //
 7         // GET: /Admin/Frame/
 8         #region Fields
 9 
10         private readonly IAdminService _adminService;
11         private readonly IAdminAuthorityService _adminAuthorityService;
12         private readonly IAdminRoleService _adminRoleService;
13         private readonly ILogService _logService;
14 
15 
16         #endregion
17 
18         #region Constructors
19 
20       
21 
22         public FrameController(IAdminService adminService, IAdminAuthorityService adminAuthorityService, IAdminRoleService adminRoleService, ILogService logService)
23         {
24             this._adminService = adminService;
25             this._adminAuthorityService = adminAuthorityService;
26             this._adminRoleService = adminRoleService;
27             this._logService = logService;
28         }
29         #endregion
30 
31         #region Admin
32 
33           public ActionResult GetValidatorGraphics()
34             {
35                 string code = _adminService.NewValidateCode();
36                 Session["ValidatorCode"] = code;
37                 byte[] graphic =           _adminService.NewValidateCodeGraphic(code);
38                 return File(graphic, @"image/jpeg");
39         }
40         #endregion
41     }
42 }
GetValidatorGraphics

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

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

1            <div class="editor-filed">
2                 <img id="valiCode" src="@Url.Action("GetValidatorGraphics", "Frame")" title="看不清?点击更换图片。" />
3                 <input data-val="true" data-val-required="请按图填定验证码中的字母。" type="text" name="ValidatorCode"
4                     style="width: 60px;" />
5                 @Html.ValidationMessage("ValidatorCode")
6               </div>        

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

  生成的效果在这:

  

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

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

  

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

 

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

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

  

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

posted @ 2013-11-30 20:39  我佛慈悲纠结  阅读(4011)  评论(2编辑  收藏  举报