一、目录
1、多层架构+MVC+EF+AUTOFAC+AUTOMAPPER;
2、MVC中验证码的实现(经常用,记录备用)
二 正文
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 }
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 }
没什么好稀奇,就是调用基础设施层的两个方法。
到这,我们的菜的“调料”已经备齐,下一步就是“炒菜”了。
在你自己认为合适的控制器中新建一个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 }
在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>
给img标签添加click事件,点击过后重新访问生成验证码的action,由于验证中数字是随机生成的,新返回的验证码图片就不一样了。避免浏览器缓存影响,src链接附件了一个随机时间。
有需要的同学们copy CreateValidateCode,CreateValidateGraphic ……
下一篇,我们搭建Ligerui 的官网首页:http://www.ligerui.com/