1 [DefaultProperty("Text")]
2 [ToolboxData("<{0}:ValidateCode runat=server></{0}:ValidateCode>")]
3 public class ValidateCode : WebControl
4 {
5 /// <summary>
6 /// 记录随机生成的验证码
7 /// </summary>
8 private string _checkCode = string.Empty;
9
10 /// <summary>
11 /// 用于记录验证码的位数,初始值为4
12 /// </summary>
13 private int _codeLen = 4;
14
15 /// <summary>
16 /// Bindable:用于设置该属性是否可以绑定数据
17 /// Category:设置属性显示在“按分类顺序”模式时,分组的类别名称
18 /// Browsable:是否显示在控件的属性面板中
19 /// DefaultValue:指定属性的默认值
20 /// Description:指定属性的说明文字
21 /// </summary>
22 [Bindable(true), Category("Appearance"), Browsable(true), DefaultValue(true), Description("此属性用于设置验证码的长度")]
23 public int CodeLength
24 {
25 get
26 {
27 return _codeLen;
28 }
29 set
30 {
31 _codeLen = value;
32 }
33 }
34
35 /// <summary>
36 /// 生成随机验证码
37 /// </summary>
38 /// <returns></returns>
39 private string GetValidateCode()
40 {
41 //创建一个字符数组,用于存储组成验证码的数字和英文字母
42 char[] s = new char[]{'2','3','4','5','6','7','8','9','a'
43 ,'b','c','d','e','f','g','h','i','j','k','m','n','p','q'
44 ,'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G'
45 ,'H','I','J','K','L','M','N','P','Q','R','S','T','U','V','W'
46 ,'X','Y','Z'};
47 string num = "";//创建变量用于记录指定长度的验证码的值
48 Random r = new Random();//生成随机生成器
49 //根据用户需要的长度来定义验证码的位数
50 for (int i = 0; i < _codeLen; i++)
51 {
52 num += s[r.Next(0, s.Length)].ToString();
53 }
54 return num;//返回生成的随机验证码的值
55 }
56
57 /// <summary>
58 /// 绘制图形验证码
59 /// </summary>
60 /// <param name="checkCode">随机生成的验证码</param>
61 private void CreateCheckCodeImage(string checkCode)
62 {
63 System.Drawing.Bitmap image = new System.Drawing.Bitmap((int)Math.Ceiling((checkCode.Length * 14.5)), 22);//创建画布,用于绘制验证码
64 Graphics g = Graphics.FromImage(image);//声明Graphics对象
65 try
66 {
67 Random random = new Random(); //生成随机生成器
68 g.Clear(Color.White); //清空图片背景色
69 Font font = new System.Drawing.Font("宋体", 15, (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic));//设置字体
70 System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Green, Color.Red, 1.2f, true);//设置笔刷
71 g.DrawString(checkCode, font, brush, 0, 0);//将验证码绘制到画布中
72 for (int i = 0; i < 100; i++) //画图片的前景噪音点
73 {
74 int x = random.Next(image.Width);
75 int y = random.Next(image.Height);
76 image.SetPixel(x, y, Color.FromArgb(random.Next()));
77 }
78 HttpContext.Current.Response.Cookies["code"].Value = checkCode;//将验证码存入cookie中
79 //画图片的边框线
80 g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
81 System.IO.MemoryStream ms = new System.IO.MemoryStream();//创建内存流
82 image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);//将验证码图片存入内存流
83 Page.Response.Clear();//清除缓冲区流中所有内容输出
84 Page.Response.ContentType = "image/GIF";//设置输出流类型
85 Page.Response.BinaryWrite(ms.ToArray());//写入输出流
86 Page.Response.Flush();//向客户端发送输出流
87 ms.Close();//释放资源
88 ms.Dispose();//释放资源
89 Page.Response.End();
90 }
91 catch (Exception ex)
92 {
93 throw ex;
94 }
95 finally
96 {
97 g.Dispose();
98 image.Dispose();
99 }
100 }
101
102 /// <summary>
103 /// 控件加载事件
104 /// </summary>
105 protected override void OnLoad(EventArgs e)
106 {
107 base.OnLoad(e);
108 try
109 {
110 string sn = Page.Request.QueryString["_ImageTag"];//获取页面传递的参数
111 if (sn != null)//判断参数是否为空,如果不为空时才能生成验证码,并绘制输出到页面
112 {
113 _checkCode = GetValidateCode();//生成验证码
114 CreateCheckCodeImage(_checkCode);//绘制输出到页面
115 }
116 else
117 {
118 //创建一个JavaScript函数用于生成随机数
119 string script = @"<script language='JavaScript'>
120 function getnum()
121 {
122 var num=Math.floor(Math.random()*100);
123 return num;
124 }
125 </script>";
126 //将该方法注册到控件所在的页面中
127 Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "getnum", script);
128 }
129 }
130 catch { }
131 }
132
133 protected override void RenderContents(HtmlTextWriter output)
134 {
135 string CID = string.Empty;
136 try
137 {
138 if (string.IsNullOrEmpty(_checkCode))//首先判断是否生成了验证码
139 {
140 CID = this.UniqueID + "img";//设置页面IMG的ID值
141 //输出表格到页面
142 output.Write("<table cellpadding=\"0\" cellspacing=\"0\" >");
143 output.Write("<tr>");
144 output.Write("<td>");
145 output.Write("<img border=\"0\" src=\"{0}\" id=\"{1}\"/>", this.Page.Request.Path + "?_ImageTag=" + DateTime.Now.Second, CID);//输出img图片,并且指定其src地址,因为验证码控件是被输出到当前的页面中,所以接收当前页面地址作为图片的数据源
146 output.Write("</td>");
147 output.Write("<td>");
148 output.Write("<a style=\"cursor:pointer;font-size:small\" onclick=\"document.getElementById('" + CID + "').src=" + "'" + this.Page.Request.Path + "?_ImageTag='" + "+getnum()" + "\"" + "> 看不清?</a>");//创建一个连接,单击后无刷新更换验证码
149 output.Write("</td>");
150 output.Write("</tr>");
151 output.Write("</table>");
152 }
153 }
154 catch
155 {
156 output.Write("<table cellpadding=\"0\" cellspacing=\"0\" >");
157 output.Write("<tr>");
158 output.Write("<td>");
159 output.Write("</td>");
160 output.Write("<td>");
161 //显示“看不清?”链接
162 output.Write("<a style=\"cursor:pointer;font-size:small\"" + "> 看不清?</a>");
163 output.Write("</td>");
164 output.Write("</tr>");
165 output.Write("</table>");
166 }
167 }
168
169 /// <summary>
170 /// 公共方法用于验证输入的验证码是否正确
171 /// </summary>
172 public bool CheckSN(string sn)
173 {
174 bool flag = false;
175 if (HttpContext.Current.Request.Cookies["code"].Value != null)//如果cookie不为空
176 {
177 flag = sn.ToLower() == HttpContext.Current.Request.Cookies["code"].Value.ToString().ToLower();//判断记录的cookie与输入的验证码是否一致
178 }
179 return flag;
180 }
181
182 }