ASP.net验证码控件(附源代码)

前段时间接了个网站做,里面有用到验证码,本着节省时间的想法,上网找了一下相关的控件,
没想到这样的控件竟然很少,网上找到的大多是类似asp那样把一个单独aspx页面作为图片的方式的,
(例如:<img src="code.aspx">)以控件形式写的极少,而且写的很差劲,用处不大。 
  刚好那几天没什么事,干脆自己写个验证码的控件算了,一来以后可以再次使用,省去再写的时
间,二来也练下asp.net服务器控件的写法,毕竟目前还没写过正式的服务器控件。

  控件特点:
  1、自动完成客户端服务器的验证码验证,只要直接拖到页面即可自动验证。
  2、可自定义验证码图片外观。
  3、有数字、小写字母、大写字母三种及任意两种组合、三种组合字符选择。

  下面说下这个控件的开发的一点心得,只写思路要点,详细的请看源代码。


  要点一:图片的生成处理。
  要在Web上动态生成一个图片并显示出来,目前常用的做法是把一个页面作为一个图片,然后在
这个页面上用 HttpResponse
.BinaryWrite(byte[] imageBuffer) 的方法输出图像流。
  当然,还得指定ContentType,例如:Response.ContentType = "image/Gif"
  至于imageBuffer的方式最简单的可以用 Bitmap.Save(Stream stream, ImageFormat format)以及
Stream
.ToArray() 方法获得。
  至于怎么生成随机符的图片,网上有很多例子,就不多说了。

  要点二:处理图片的页面。
  图像的输出没问题了,但是去哪里找到这样一个输出的页面呢,当然不能单独做出一个页面来,这
样做的话那就没什么服务器换件的意义了。
  WebControl这个类下面有个属性Page
,这是指定包含本服务器控件的页面,所以,我们可以考虑
用这个属性所指定的页面来输出图片。
  但是这样问题也来了,既要用这个页面输出整个控件,也要用它输出图片,这样就得有个判断了,
我们可以用Request.QueryString
来判断,图片的地址就加个查询字符串,例如:<img src="?isImage=
true">
(?其实是指定src地址为空,这样就会链接到当前页面),
然后在RenderContents的时候再这个
查询字符串来输出HTML,例如:
  if(string.IsNullOrEmpty(HttpContext.Current.Request.QueryString[isImage])
    输出控件HTML
  else
    输出图片

  
(注意:上方中的获取查询字符串要用HttpContext.Current.Request或者Page.Request

  
要点三:客户端验证。
  客户端的验证主要是验证是否输出为空或者输入长度是否正确。
  客户端验证的方法很简单,只要在控件所在的Form提交的时候执行检查代码即可。代码如下:
  document.forms['" + this.Page.Form.ClientID + "'].attachEvent('onsubmit',checkCode);
  其中的checkCode是检查的函数名。

  
要点四:服务端验证。
  服务端的验证也很简单,只要比较Request.Form[key] Session[key]的值即可。
  当然,为了方便控件的使用,要给控件加个属性,指示是否通过验证。代码如下:
  public bool IsMach
        {
            get
            {
                return HttpContext.Current.Request.Form[textID].ToString() == HttpContext.Current.
Session[textID].ToString();
            }
        }




  以上的是整个控件开发的思路,以经包含了整个控件的内容了,不过为了使控件更加方便使用,还要
做一些,比如加一些可以由用户更改的属性,公开一些函数给别人重载等等。
  
  
一:函数重载。
  函数重载的不多说了,这个控件只有一个可以重载的函数,
  GetBitmap(string codeText, ImageStyle imgStyle)
如果使用者不喜欢这个控件内定的图片方式的话可以继承这个控件,然后重载这个函数,就可以自己输出
喜欢的图片了。

  二:属性。
  要做出方便用户使用的控件,公开的属性当然不能少。
  这个控件的属性有好几个,大多是控制外观的,也没有什么好写的,不过有个属性是复杂属性(就是
整个属性是一个类的实例,例如常见的 Control.Font 
以也可以分享下。控件里的代码如下:
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Category("外观扩展"), Description("验证码图像样式"),TypeConverter(typeof(ImageStyleTypeConver)) ]
        public ImageStyle ImageStyle
        {
            get
            {
                return imageStyle;
            }
        }
        ImageStyle imageStyle = new ImageStyle();
  
  实现这样一个复杂属性的好处是可以在 Visual Studio IDE 里的属性面板直接更改其属性值,如下图:

 
     

  或者在aspx代码里面更改,例如:
     <cc1:AuthCode ID="AuthCode1" runat="server"
        ImageStyle-ImgBgColor="White" ImageStyle-ImgBorderColor="DeepSkyBlue"     ImageStyle-ImgNoiseColor="Ivory" ImageStyle-TextColor1="Azure"  
        ImageStyle-TextColor2="GhostWhite" />


 
 实现这种功能的关键在于 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
以及 TypeConverter(typeof(ImageStyleTypeConver))  这两个地方。
 
 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 提示属性更改好生成
ImageStyle-ImgBgColor="White"
这种代码,至于 TypeConverter(typeof(ImageStyleTypeConver)) 
则主要用于类型转换,具体的见代码里的 ImageStyleTypeConver 类,该类是继承于
ExpandableObjectConverter
类的,并且需要实现下面四个重载:
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
}


 
  控件使用实例:
  往页面中拖入控件后,在代码中如下使用:
  if (AuthCode1.IsMach)
  {
    if(检查用用户名和密码)   Response.Redirect("test.aspx");
  }




  
控件运行的截图:
  

  

  源代码,里面test目录为使用实例:
  

    
    该控件已更新,请到以下地址下载最新版

http://www.cnblogs.com/9422e/archive/2010/01/18/1650299.html

 

posted @ 2011-03-15 10:22  爱军  阅读(726)  评论(0编辑  收藏  举报