设计者:王海波 2004-11-20
Asp.net的设计方式和设计理念和其他的如Asp,Jsp,Php,Perl
等都不一样,几乎是完全的面向对象设计!代码的复用就是其
中差异较大的特点之一,Asp.net除了可以用Include以外,还提供
了比较有特点的Web控件,包括:Ascx形式和带设计时支持的控
件[本文属于后者],为了熟悉这些新概念,我自己写了个Web控件。
在实际项目中运行使用良好,以后,要有时间,我还将不断改进。
ValidateCode控件的使用方法:
第一步:
编译我提供的原代码, 然后,在Studio.net 2003工具栏上, 选择"添加/移除项", 选中编译好的dll文件。
第二步:
工具栏上就会多一个Web控件ValidateCode,做好一个Web窗体,在Studio.net 2003开发界面上,直接把控件拖到WebForm上,就OK!
第三步:
在该控件的GraphicOK事件中获取,验证码的字符信息,用于和用户录入做比较!
最后一步:
在网站的根目录下,建一个temp目录(也可以自己指定目录),用于存放验证码
图片,不用担心,代码会自动删除无用的图片!
原代码如下:
1using System;
2using System.Web.UI;
3using System.Web.UI.WebControls;
4using System.ComponentModel;
5using System.IO;
6using System.Drawing;
7using System.Drawing.Drawing2D;
8using System.Drawing.Imaging;
9
10namespace WebValidateCode
11{
12 /**//// <summary>
13 /// ValidateCode 的摘要说明。
14 /// 设计者:王海波 2004-11-20
15 /// </summary>
16 ///
17 public enum GraphicType
18 {
19 Jpg = 0,
20 Gif = 1,
21 Png = 2,
22 Bmp = 3,
23 }
24
25
26 //[ToolboxBitmap(@"D:\DotnetApp\ValidateCode\ValidateCode.bmp") ] //设置控件在工具箱上的图标
27 public class ValidateCode : System.Web.UI.WebControls.WebControl ,INamingContainer
28 {
29 private int pCodelen=5;
30 private int pChartWidth=100;
31 private int pChartHeight=20;
32
33 private GraphicType pChartType;
34
35 private string pAuthenCode;
36
37 private string pTempImageURLPath="/temp";
38 private string pAuthenImageFullname;
39 private string pAuthenImageFullURL;
40
41 //生成校验码的变量 start
42 private Bitmap validateImage;
43 private Graphics g;
44 //生成校验码的变量 End
45
46 private TextBox txt=new TextBox();
47 private System.Web.UI.WebControls.Image img= new System.Web.UI.WebControls.Image();
48
49 定义控件事件#region 定义控件事件
50
51 public delegate void GraphicCreated(object sender, EventArgs e);
52 public event EventHandler GraphicOK; //在校验图片生成结束以后触发
53
54 protected virtual void OnGraphicOK(object sender, EventArgs e)
55 {
56 if (GraphicOK != null)
57 {
58 //Invokes the delegates.
59 GraphicOK(sender, e);
60 }
61 }
62
63 #endregion
64
65 控件属性#region 控件属性
66
67 //生成校验码的长度
68 [Bindable(true),Browsable(true),Category("Appearance"),DefaultValue(true),Description("需要验证码的长度,建议在5~8位之间!")]
69 public int CodeLength
70 {
71 get
72 {
73 return pCodelen;
74 }
75
76 set
77 {
78 pCodelen = value;
79 }
80 }
81
82 //生成校验码的长度
83 [Bindable(true),Browsable(true),Category("Appearance"),DefaultValue(true),Description("生成验证码图片的临时存放路径,要求必须是网站下的虚拟目录!")]
84 public string TempImageURLPath
85 {
86 get
87 {
88 return pTempImageURLPath;
89 }
90
91 set
92 {
93 pTempImageURLPath = value;
94 }
95 }
96
97 [Bindable(true),Browsable(true),Category("Appearance"),DefaultValue(GraphicType.Jpg),Description("选择生成校验图文件的类型(Jpg;Gif;Png;Bmp)!")]
98 public GraphicType ChartType
99 {
100 get
101 {
102 return pChartType;
103 }
104
105 set
106 {
107 pChartType = value;
108 }
109 }
110
111
112 //生成校验码图片的宽度
113 public int ChartWidth
114 {
115 get
116 {
117 return pChartWidth;
118 }
119
120 set
121 {
122 pChartWidth = value;
123 }
124 }
125
126 //生成校验码图片的高度
127 public int ChartHeight
128 {
129 get
130 {
131 return pChartHeight;
132 }
133
134 set
135 {
136 pChartHeight = value;
137 }
138 }
139
140 //需要生成的校验码
141 public string AuthenCode
142 {
143 get
144 {
145 return pAuthenCode;
146 }
147
148 set
149 {
150 pAuthenCode = value;
151 }
152 }
153
154 #endregion
155
156 /**//// <summary>
157 /// 将此控件呈现给指定的输出参数。
158 /// </summary>
159 /// <param name="output"> 要写出到的 HTML 编写器 </param>
160 protected override void Render(HtmlTextWriter output)
161 {
162
163 System.Web.UI.WebControls.Image objImage;
164 //TextBox objTxt;
165
166
167 //绘制包含的控件
168 objImage = (System.Web.UI.WebControls.Image) Controls[0];
169 //objTxt = (TextBox) Controls[1];
170
171 if(pAuthenCode==null)
172 pAuthenCode=GetValidateCode();
173
174 OnGraphicOK(this,EventArgs.Empty );
175
176 GetRandomImage(pAuthenCode);
177 objImage.ImageUrl=pAuthenImageFullURL;
178
179 objImage.RenderControl(output);
180
181 }
182
183 /**//// <summary>
184 /// 给控件添加子控件
185 /// </summary>
186 protected override void CreateChildControls( )
187 {
188
189 //Controls.Add(btn);
190 Controls.Add(img);
191 //Controls.Add(txt);
192 }
193
194 /**//// <summary>
195 /// 控件Load时候属性的初始化
196 /// </summary>
197 /// <param name="e"></param>
198 protected override void OnLoad(System.EventArgs e)
199 {
200 EraseOldGraphic(); //删除过期的图片
201 }
202
203 /**//// <summary>
204 /// 生成随机的
205 /// </summary>
206 private void MakeRandomFileName()
207 {
208 string strRandName=DateTime.Now.Ticks.ToString()+".jpg";
209 pAuthenImageFullname=this.Page.MapPath(TempImageURLPath)+@"\"+strRandName;
210 pAuthenImageFullURL=TempImageURLPath+"/"+strRandName;
211 }
212
213
214 private void GetRandomImage(string strValidateCode)
215 {
216 //生成随即图片的全名,和全URL
217 MakeRandomFileName();
218
219 validateImage = new Bitmap(pChartWidth, pChartHeight, PixelFormat.Format24bppRgb); // .Format24bppRgb);
220 g = Graphics.FromImage(validateImage);
221
222 g.Clear(Color.LightGray) ;
223
224 //g.DrawString(strValidateCode , new Font("宋体",16,FontStyle.Bold),new SolidBrush(Color.DarkRed),new PointF(2,2));
225
226 for(int i=0;i<strValidateCode.Length;i++)
227 {
228 Random r = new Random();
229 PointF startPos=new PointF(r.Next(3,6)+(r.Next(12,14)*i ),r.Next(-1,2) );
230
231 g.DrawString(strValidateCode.Substring(i,1) , new Font("宋体",14,FontStyle.Italic),new SolidBrush(Color.Blue),startPos);
232 }
233
234
235 //g.FillRectangle(new LinearGradientBrush(new Point(0,0), new Point(120,30), Color.FromArgb(0,0,0,0),Color.FromArgb(255,255,255,255)),0,0,120,30);
236 switch(pChartType)
237 {
238 case GraphicType.Jpg:
239
240 validateImage.Save(pAuthenImageFullname, ImageFormat.Jpeg);
241 break;
242
243 case GraphicType.Gif:
244
245 validateImage.Save(pAuthenImageFullname, ImageFormat.Gif);
246 break;
247
248 case GraphicType.Png:
249
250 validateImage.Save(pAuthenImageFullname, ImageFormat.Png);
251 break;
252
253 case GraphicType.Bmp:
254
255 validateImage.Save(pAuthenImageFullname, ImageFormat.Bmp);
256 break;
257
258 default:
259 validateImage.Save(pAuthenImageFullname, ImageFormat.Jpeg);
260 break;
261
262 }
263
264 validateImage.Dispose();
265
266 g.Dispose();
267
268
269
270 }
271
272 /**//// <summary>
273 /// 动态从数字和字母组成的元素中动态选择生成校验码
274 /// </summary>
275 private string GetValidateCode()
276 {
277 char[] s = new char[]{'0','1', '2','3','4','5','6','7','8','9','a'
278 ,'b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q'
279 ,'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G'
280 ,'H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W'
281 ,'X','Y','Z'};
282 string num = "";
283 Random r = new Random();
284
285 //根据用户需要的长度来定义验证码的位数
286 for(int i = 0; i < CodeLength; i++)
287 {
288 num += s[r.Next(0, s.Length)].ToString();
289 }
290
291 return num;
292 }
293
294 /**//// <summary>
295 /// 清除时间超过20秒的临时图片记录
296 /// </summary>
297 /// <returns>成功返回true,失败返回false</returns>
298 public bool EraseOldGraphic()
299 {
300
301 try
302 {
303 DirectoryInfo Dinfo=new DirectoryInfo(this.Page.MapPath(pTempImageURLPath));
304 FileInfo[] FileSet;
305
306 if(Dinfo.Exists)
307 {
308 switch(pChartType)
309 {
310 case GraphicType.Jpg:
311
312 FileSet=Dinfo.GetFiles("*.jpg");
313 break;
314
315 case GraphicType.Gif:
316
317 FileSet=Dinfo.GetFiles("*.gif");
318 break;
319
320 case GraphicType.Png:
321
322 FileSet=Dinfo.GetFiles("*.png");
323 break;
324
325 case GraphicType.Bmp:
326
327 FileSet=Dinfo.GetFiles("*.bmp");
328 break;
329
330 default:
331 FileSet=Dinfo.GetFiles("*.jpg");
332 break;
333
334 }
335
336 foreach(FileInfo fileInfo in FileSet)
337 {
338 if(fileInfo.Exists)
339 {
340 DateTime dts=DateTime.Now;
341 DateTime dtc=fileInfo.CreationTime;
342
343 TimeSpan ts=dts-dtc;
344
345 if(ts.Seconds>20)
346 {
347 fileInfo.Delete();
348 }
349 }
350 }
351 }
352
353 return true;
354 }
355 catch(IOException ioe)
356 {
357 return false;
358 }
359 }
360 }
361}
362
363
使用方法举例:
先在 Page_Load 中加入: this.vcode.GraphicOK += new System.EventHandler(this.vcode_GraphicOK);
然后就可以在GraphicOK事件中用AuthenCode属性获取内容:
1private void Page_Load(object sender, System.EventArgs e)
2{
3this.vcode.GraphicOK += new System.EventHandler(this.vcode_GraphicOK);
4}
5
6private void vcode_GraphicOK(object sender, System.EventArgs e)
7{
8Session["vcode"]= vcode.AuthenCode;
9}
10
如果出现错误信息:“GDI+ 中发生一般性错误”,一般是因为NTFS目录权限设置不正确,要赋予 Everyone 用户组对临时目录(如:/temp)的读写修改权限。