一、目錄
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/