zoukankan      html  css  js  c++  java
  • 实现验证码控件代码验证控件,方便使用验证码(修改)

      网站在进行重要操作步骤时,为了防止攻击,一般都采用生成验证码的方法。为了使用方便,我自己写了一个从BaseValidator实现的验证控件,负责给指定的Image控制设置ImageSrc并在验证失败时,清空TextBox控制的值。从BaseValidator继承,是因为服务端只需调用
     if(Page.IsValid){} 
    就可以了。

    下面主要代码公布如下,希望大家拍砖。
    使用代码示例:
                            <asp:TextBox ID="TextBox1" runat="server" AutoCompleteType="Disabled"  ></asp:TextBox>
                            
    <asp:Image ID="Image1" runat="server" ImageAlign="absMiddle" />
                            
    <asp:ImageValidator runat="server" ID="imagevalidator" 
              ImageControl
    ="Image1" 
              ControlToValidate
    ="TextBox1" 
              Display
    ="Dynamic"
              CharCount
    ="4" 
              Fonts
    ="宋体,Gungsuh,仿宋,黑体" 
              BgColor
    ="White" 
              MaxFontSize
    ="16" 
              MinFontSizePercent
    ="50" 
              ErrorMessage
    ="验证码错误!" 
              SetFocusOnError
    ="True" />
    后台编码:
            protected void OnLogin(object sender, EventArgs e)
            
    {
                
    try
                
    {
                    
    if (Page.IsValid)
                    
    {
                        
    string hashedPwd = Utility.Md5.HashedString(this.tbLoginPassword.Text.Trim());
                        Manager manager 
    = Manager.CreateInstance(this.tbLoginName.Text.Trim(), hashedPwd);
                        
    //登陆成功
                        ManagePageBase.SetAuthSession(manager);
                                                              System.Web.Security.FormsAuthentication.RedirectFromLoginPage(manager.Name, 
    false);
                    }

                }

                
    catch (BusinessException ex)
                
    {
                    
    this.ShowMessage(ex.Message);
                }

            }


    实现代码如下:
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.ComponentModel;
    using System.Web.Configuration;
    using System.Drawing.Design;
    using System.Drawing;
    using System.Web.SessionState;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Drawing.Imaging;
    using System.Drawing.Drawing2D;

    namespace Iyond.Web.UI.WebControls
    {
        
    public class ImageValidator : System.Web.UI.WebControls.BaseValidator
        
    {

            
    private string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            [Bindable(
    false)]
            [Category(
    "Data")]
            [DefaultValue(
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")]
            [Localizable(
    true)]
            [Description(
    "用于生成验证码的源字符")]
            
    public string Chars
            
    {
                
    get
                
    {
                    
    return _chars;
                }


                
    set
                
    {
                    _chars 
    = value;
                }

            }


            
    private int _charCount = 5;
            [Bindable(
    false)]
            [Category(
    "Data")]
            [DefaultValue(
    5)]
            [Localizable(
    true)]
            [Description(
    "验证码中字符的数量")]
            
    public int CharCount
            
    {
                
    get
                
    {
                    
    return _charCount;
                }

                
    set
                
    {
                    _charCount 
    = value;
                }

            }


            
    private string _pageValidateCode = "~/IyondValidateCode.aspx";
            [Category(
    "Data")]
            [Localizable(
    true)]
            [Description(
    "在Web.config中的HttpHandler节中配置的读取验证码的页面")]
            
    public string ValidateCodePage
            
    {
                
    get return _pageValidateCode; }
                
    set { _pageValidateCode = value; }
            }



            
    private int _minFontSizePercent = 60;
            [Category(
    "Data")]
            [Localizable(
    true)]
            [Description(
    "字体最小高度占Image控件高度的百分比")]
            
    public int MinFontSizePercent
            
    {
                
    get
                
    {
                    
    return _minFontSizePercent;
                }

                
    set
                
    {
                    
    if (value > 100)
                        
    throw new ArgumentOutOfRangeException("MaxFontSize", value, "最大为100(表示100%)");
                    
    if (value < 50)
                        
    throw new ArgumentOutOfRangeException("MaxFontSize", value, "最小为50(表示50%)");

                    _minFontSizePercent 
    = value;
                }

            }



            
    public int MinFontSize
            
    {
                
    get
                
    {
                    
    return Convert.ToInt32(this.MaxFontSize * this.MinFontSizePercent / 100 + 1);
                }

            }


            
    private int _maxFontSize = 100;
            [Category(
    "Data")]
            [Localizable(
    true)]
            [Description(
    "字体最大高度占Image控件高度的百分比")]
            
    public int MaxFontSize
            
    {
                
    get
                
    {
                    
    return _maxFontSize;
                }

                
    set
                
    {
                    
    if (value > 100)
                        
    throw new ArgumentOutOfRangeException("MaxFontSize", value, "最大为100");
                    
    if (value < 6)
                        
    throw new ArgumentOutOfRangeException("MaxFontSize", value, "最小为6");
                    _maxFontSize 
    = value;
                }

            }


            
    private Color _fontColor = Color.Black;
            [Category(
    "Data")]
            [Localizable(
    true)]
            [Description(
    "字体颜色")]
            
    public Color FontColor
            
    {
                
    get
                
    {
                    
    return _fontColor;
                }

                
    set
                
    {
                    _fontColor 
    = value;
                }

            }


            
    private Color _bgColor = Color.White;
            [Category(
    "Data")]
            [Localizable(
    true)]
            [Description(
    "字体颜色")]
            
    public Color BgColor
            
    {
                
    get
                
    {
                    
    return _bgColor;
                }

                
    set
                
    {
                    _bgColor 
    = value;
                }

            }


            
    private bool _ignoreCase = true;
            [Category(
    "Data")]
            [Localizable(
    true)]
            [Description(
    "是否乎略大小写")]
            
    public bool IgnoreCase
            
    {
                
    get return _ignoreCase; }
                
    set { _ignoreCase = value; }
            }


            
    private bool _enableChangeImage = true;
            [Category(
    "Data")]
            [Localizable(
    true)]
            [Description(
    "是否允许更换图片")]
            
    public bool EnableChangeImage
            
    {
                
    get return _enableChangeImage; }
                
    set { _enableChangeImage = value; }
            }


            
    private int _maxRotate = 45;
            [Category(
    "Data")]
            [Localizable(
    true)]
            [Description(
    "每个字的最大旋转角度")]
            
    public int MaxRotate
            
    {
                
    get return _maxRotate; }
                
    set { _maxRotate = value; }
            }


            
    private List<string> _fonts = new List<string>();
            [Category(
    "Data")]
            [Localizable(
    true)]
            [Description(
    "字体列表,从中随机选择")]
            [Editor(
    "System.Windows.Forms.Design.StringArrayEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
            
    typeof(UITypeEditor)), TypeConverter(typeof(FontNamesConverter)),
            RefreshProperties(RefreshProperties.Repaint), 
            NotifyParentProperty(
    true)]
            
    public string[] Fonts
            
    {
                
    get
                
    {
                    
    return _fonts.ToArray();
                }

                
    set
                
    {
                    
    if (value == null)
                        
    throw new ArgumentNullException("Fonts");

                    _fonts.Clear();
                    _fonts.AddRange(value);
                }

            }




            
    private static Dictionary<string, ImageValidatorConfig> runtimeConfig = new Dictionary<string, ImageValidatorConfig>();

            
    /// <summary>
            
    /// 查询验证码配置
            
    /// </summary>
            
    /// <param name="sign">验证码标识</param>
            
    /// <returns></returns>

            public static ImageValidatorConfig GetConfig(string sign)
            
    {
                
    if (!runtimeConfig.ContainsKey(sign))
                    
    throw new ArgumentOutOfRangeException("sign", sign);

                
    return runtimeConfig[sign] as ImageValidatorConfig;
            }



            
    /// <summary>
            
    /// 计算是不是合法(验证码是不是正确)
            
    /// </summary>
            
    /// <returns></returns>

            protected override bool EvaluateIsValid()
            
    {
                
    bool isValid = false;
                
    string text1 = base.GetControlValidationValue(base.ControlToValidate);
                
    if ((text1 == null|| (text1.Trim().Length == 0))
                
    {
                    isValid 
    = false;
                }

                
    else
                
    {
                    isValid 
    = this.ValidateChar();
                }


                
    this.IsValid = isValid;
                
    return this.IsValid;


            }


            
    /// <summary>
            
    /// 查看是不是合法
            
    /// </summary>
            
    /// <returns></returns>

            private bool ValidateChar()
            
    {
                
    string validatecode = ValidateCodeHandler.GetAndEmptyValidateCode(this.ValidateSign);
                
    if (string.IsNullOrEmpty(validatecode))
                
    {
                    
    return false;
                }

                
    else
                
    {
                    
    return string.Compare(validatecode, this.GetControlValidationValue(this.ControlToValidate), this.IgnoreCase) == 0;
                }

            }

            
    /// <summary>
            
    /// 关联的图片控件ID
            
    /// </summary>

            [DescriptionAttribute("BaseValidator_ImageControl"), IDReferenceProperty, TypeConverter(typeof(ImageControlConverter)), Themeable(false), DefaultValue(""), CategoryAttribute("Behavior")]
            
    public string ImageControl
            
    {
                
    get
                
    {
                    
    object obj1 = this.ViewState["ImageControl"];
                    
    if (obj1 != null)
                    
    {
                        
    return (string)obj1;
                    }

                    
    return string.Empty;
                }

                
    set
                
    {
                    
    this.ViewState["ImageControl"= value;
                }

            }


            
    protected System.Web.UI.WebControls.Image Image
            
    {
                
    get 
                
    {
                    
    if (string.IsNullOrEmpty(this.ImageControl))
                        
    throw new ArgumentNullException("ImageControl");

                    
    return this.NamingContainer.FindControl(this.ImageControl) as System.Web.UI.WebControls.Image;
                }

            }


            
    protected string ValidateSign
            
    {
                
    get
                
    {
                    
    if (ViewState["imagevalidate::validatesign"== null)
                    
    {
                        ViewState[
    "imagevalidate::validatesign"= Utility.HashedString(string.Format("{0}::{1}",Page.Request.Url.AbsolutePath,this.UniqueID));
                    }


                    
    return Convert.ToString(ViewState["imagevalidate::validatesign"]);
                }

            }


            
    protected override void OnPreRender(EventArgs e)
            
    {
                
    this.Image.ImageUrl = "#";
                
    this.Image.Attributes["onload"= "this.style.display=''";

                
    if (this.EnableChangeImage)
                
    {
                    Image.ToolTip 
    = "看不清楚吗?双击换一张";
                    Image.Attributes[
    "ondblclick"= "if(!this.orgsrc)this.orgsrc=this.src;this.src=this.orgsrc + '&t=' + new Date().valueOf()";
                }

                
    this.Image.Style.Add(HtmlTextWriterStyle.Display, "none");
                StringBuilder sbjs 
    = new StringBuilder();
                sbjs.AppendFormat(
    "javascript:this.onerror=null;this.src='{0}?sign={1}';", Page.ResolveClientUrl(this.ValidateCodePage), this.ValidateSign);

                
    this.Image.Attributes.Add("onerror", sbjs.ToString());

                runtimeConfig[
    this.ValidateSign] = new ImageValidatorConfig(this.Chars, this.CharCount,this.FontColor, 
                    
    this.Fonts,this.MinFontSize, this.MaxFontSize);

                
    if (!this.IsValid)
                
    {
                    ITextControl textInput 
    = this.NamingContainer.FindControl(this.ControlToValidate) as ITextControl;
                    
    if (textInput != null)
                    
    {
                        textInput.Text 
    = "";
                    }


                }



                
    base.OnPreRender(e);
            }

                


        }


        
    /// <summary>
        
    /// 查找Image控件ID列表
        
    /// </summary>

        public class ImageControlConverter : ControlIDConverter
        
    {
            
    protected override bool FilterControl(Control control)
            
    {
                
    if (control is System.Web.UI.WebControls.Image)
                    
    return true;
                
    else
                
    {
                    
    return false;
                }

                
            }

        }


        
    /// <summary>
        
    /// 控制配置类
        
    /// </summary>

        public class ImageValidatorConfig
        
    {
            
    private string _chars = string.Empty;

            
    /// <summary>
            
    /// 可用字符列表构成的串
            
    /// </summary>
            
    /// <example>
            
    /// 123456789
            
    /// </example>

            public string Chars
            
    {
                
    get
                
    {
                    
    return _chars;
                }


                
    set
                
    {
                    _chars 
    = value;
                }

            }


            
    private int _charCount = 5;

            
    /// <summary>
            
    /// 验证图片上字符数量
            
    /// </summary>

            public int CharCount
            
    {
                
    get
                
    {
                    
    return _charCount;
                }

                
    set
                
    {
                    _charCount 
    = value;
                }

            }

            
    private int _minFontSize = 60;

            
    /// <summary>
            
    /// 字体最小高度占Image控件高度的百分比
            
    /// </summary>

            public int MinFontSize
            
    {
                
    get
                
    {
                    
    return _minFontSize;
                }

                
    set
                
    {
                    _minFontSize 
    = value;
                }

            }

            
    private int _maxFontSize = 100;

            
    /// <summary>
            
    /// 字体最大高度占Image控件高度的百分比
            
    /// </summary>

            public int MaxFontSize
            
    {
                
    get
                
    {
                    
    return _maxFontSize;
                }

                
    set
                
    {
                    _maxFontSize 
    = value;
                }

            }


            
    private Color _fontColor = Color.Black;

            
    /// <summary>
            
    /// 字符颜色
            
    /// </summary>

            public Color FontColor
            
    {
                
    get
                
    {
                    
    return _fontColor;
                }

                
    set
                
    {
                    _fontColor 
    = value;
                }

            }


            
    private Color _bgColor = Color.White;

            
    /// <summary>
            
    /// 背景颜色
            
    /// </summary>

            public Color BgColor
            
    {
                
    get
                
    {
                    
    return _bgColor;
                }

                
    set
                
    {
                    _bgColor 
    = value;
                }

            }


            
    private string[] _fonts = null;

            
    /// <summary>
            
    /// 可用字体列表,生成时,会随机选择
            
    /// </summary>

            public string[] Fonts
            
    {
                
    get
                
    {
                    
    return _fonts;
                }

                
    set
                
    {
                    
    if (value == null)
                        
    throw new ArgumentNullException("Fonts");

                    
    if(value.Length == 0)
                    
    {
                        
    throw new ArgumentException("至少指定一种字体");
                    }

                    _fonts 
    = value;
                }

            }


            
    private int _maxRotate = 45;

            
    /// <summary>
            
    /// 每个字符最大旋转角度
            
    /// </summary>

            public int MaxRotate
            
    {
                
    get return _maxRotate; }
                
    set { _maxRotate = value; }
            }





            
    public ImageValidatorConfig(string chars, int charCount, Color fontColor, string[] fonts, int minFontSise, int maxFontSize)
            
    {
                
    this.Chars = chars;
                
    this.CharCount = charCount;
                
    this.FontColor = fontColor;
                
    this.MinFontSize = minFontSise;
                
    this.MaxFontSize = maxFontSize;
                
    this.Fonts = fonts;
            }

        }



        
    public class ValidateCodeHandler : System.Web.IHttpHandler, IRequiresSessionState
        
    {
            
    IHttpHandler 成员

            
    protected static string SESSIONKEY = "iyond::imagevalidator";

            
    protected static Dictionary<doubledouble> _cacheSqrt = new Dictionary<doubledouble>();

            
    /// <summary>
            
    /// 为了加快开方,自己写一个开方函数
            
    /// </summary>
            
    /// <param name="d"></param>
            
    /// <returns></returns>

            public static double Sqrt(double d)
            
    {
                
    if (_cacheSqrt.ContainsKey(d))
                    
    return _cacheSqrt[d];
                
    else
                
    {
                    
    lock (_cacheSqrt)
                    
    {
                        
    double ret = Math.Sqrt(d);
                        _cacheSqrt[d] 
    = ret;
                        
    return ret;
                    }

                }

            }


            
    /// <summary>
            
    /// 取验证码图片的字串形式,取出时清空。以防止漏洞
            
    /// </summary>
            
    /// <param name="sign">验证码配置标识</param>
            
    /// <returns></returns>

            public static string GetAndEmptyValidateCode(string sign)
            
    {
                
    if (ValidateCodeDictionary.ContainsKey(sign))
                
    {
                    
    string validatecode = ValidateCodeDictionary[sign];
                    ValidateCodeDictionary[sign] 
    = string.Empty;
                    
    return validatecode;
                }

                
    else
                
    {
                    
    return string.Empty;
                }

            }



            
    /// <summary>
            
    /// 依配置生成验证码图片
            
    /// </summary>
            
    /// <param name="sign">验证码配置标识</param>
            
    /// <returns></returns>

            public static System.Drawing.Image BuildValidateImage(string sign)
            
    {
                
    //得到验证吗生成配置
                ImageValidatorConfig config = ImageValidator.GetConfig(sign);

                
    //生成新验证码
                string validatecode = Utility.GetRandomChar(config.Chars, config.CharCount);
                ValidateCodeDictionary[sign] 
    = validatecode;

                Random random 
    = new Random();

                
    //随机生成每个字要使用的字体和大小
                List<DrawCharInfo> draws = new List<DrawCharInfo>();
                
    using (Bitmap bmpTemp = new Bitmap(11))
                
    {
                    
    using (Graphics gm = Graphics.FromImage(bmpTemp))
                    
    {
                        
    using (SolidBrush brush = new SolidBrush(config.FontColor))
                        
    {
                            
    char[] chars = validatecode.ToCharArray();
                            
    foreach (char ch in chars)
                            
    {
                                
    string fontName = config.Fonts[random.Next(0, config.Fonts.Length - 1)];
                                
    float fontSize = Convert.ToSingle(random.Next(config.MinFontSize, config.MaxFontSize));
                                Font font 
    = new Font(fontName, fontSize , FontStyle.Regular, GraphicsUnit.Pixel);

                                SizeF size 
    = gm.MeasureString(ch.ToString(), font);

                                draws.Add(
    new DrawCharInfo(ch, font, size));
                            }

                        }

                    }

                }


                
    //找出最大高度,找出图片宽度
                int bmpWidth = 0, bmpHeight = 0;
                
    foreach (DrawCharInfo dci in draws)
                
    {
                    bmpWidth 
    += Convert.ToInt32(dci.Size.Width) + 1;
                    bmpHeight 
    = Math.Max(bmpHeight, Convert.ToInt32(dci.Size.Height) + 1);
                }



                
    //依每个字符的配置,生成图片
                Bitmap bmp = new Bitmap(bmpWidth, bmpHeight);
                
    using (Graphics g = Graphics.FromImage(bmp))
                
    {
                    g.SmoothingMode 
    = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    
    using (SolidBrush brush = new SolidBrush(config.FontColor))
                    
    {
                        
    //用背景清空,将来可以考虑生成背景
                        g.Clear(config.BgColor);

                        
    //宽度计数
                        float x = 0;

                        
    foreach (DrawCharInfo dci in draws)
                        
    {
                            
    //保存场景配置
                            GraphicsState gs = g.Save();

                            
    //随机Y坐标
                            float y = random.Next(Math.Max(0, bmpHeight - Convert.ToInt32(dci.Size.Height))) / 2;

                            
    //随机旋转角度
                            float rotate = random.Next(-config.MaxRotate, config.MaxRotate);

                            
    //计算宽高
                            float halfWidth = dci.Size.Width / 2;
                            
    float halfHeight = dci.Size.Height / 2;

                            
    //变换坐标
                            g.TranslateTransform(x + halfWidth, y + halfHeight);
                            g.RotateTransform(rotate);

                            
    //打印字符
                            g.DrawString(dci.Char.ToString(), dci.Font, brush, -halfWidth, -halfHeight);

                            
    //原来场景
                            g.Restore(gs);

                            
    //增加宽度计数
                            x += dci.Size.Width;
                        }

                    }

                }


                
    //返回图片
                return bmp;

            }


            
    /// <summary>
            
    /// 保存每个标识的验证码字串
            
    /// </summary>

            protected static Dictionary<stringstring> ValidateCodeDictionary
            
    {
                
    get
                
    {
                    
    if (HttpContext.Current.Session[SESSIONKEY] == null)
                    
    {
                        HttpContext.Current.Session[SESSIONKEY] 
    = new Dictionary<stringstring>();
                    }


                    
    return HttpContext.Current.Session[SESSIONKEY] as Dictionary<stringstring>;
                }

            }

        }


        
    /// <summary>
        
    /// 每个字符的在验证吗图片的字体,大小信息
        
    /// </summary>

        internal class DrawCharInfo
        
    {
            
    private char _char;
            
    private Font _font;
            
    private SizeF _size;


            
    /// <summary>
            
    /// 字符
            
    /// </summary>

            public Char Char
            
    {
                
    get return _char; }
            }


            
    /// <summary>
            
    /// 字体
            
    /// </summary>

            public Font Font
            
    {
                
    get return _font; }
            }


            
    /// <summary>
            
    /// 字体所占区域
            
    /// </summary>

            public SizeF Size
            
    {
                
    get return _size; }
            }


            
    public DrawCharInfo(char ch, Font font, SizeF size)
            
    {
                
    this._char = ch;
                
    this._font = font;
                
    this._size = size;
            }

        }

    }


    QQ:273352165 evlon#126.com 转载请注明出处。
  • 相关阅读:
    IoC模式
    开发流程与模式
    YbSoftwareFactory
    简单的FTP文件安全识别方案
    C# 通过探测邮件服务器进行Email地址有效性检验
    YbRapidSolution for WinForm 插件生成项目总体架构介绍
    lucene.net已经从孵化器毕业
    XSql 源码开放
    TCP 套接字函数和入门级TCP编程
    C#中泛型学习笔记
  • 原文地址:https://www.cnblogs.com/evlon/p/688695.html
Copyright © 2011-2022 走看看