zoukankan      html  css  js  c++  java
  • IHttphandler之“验证码”服务器控件

    同样,先看下我们的web.config文件:

    <httpHandlers>
          <add verb="*" path="*.yy" type="Identify.LandpyHttpHander,Identify"/>
     </httpHandlers>

    首先提个问题大家见过后缀名为“yy”的文件吗,呵呵,这里实际上是使用了一个小技巧。利用IHttphandler来实现服务器端控件的事件,当点击控件时,发送一个“*.yy”路径的请求,从而实现Identify.LandpyHttpHander处理并返回客户端。

    下面上代码:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Text;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    using System.Web.SessionState;

    namespace Identify
    {
        [DefaultProperty(
    "Text")]
        [ToolboxData(
    "<{0}:LandpyIdentityControl runat=server></{0}:LandpyIdentityControl>")]
        
    public class LandpyIdentityControl : WebControl
        {
            [Bindable(
    true)]
            [Category(
    "Appearance")]
            [DefaultValue(
    "")]
            [Localizable(
    true)]
            
    public string Text
            {
                
    get
                {
                    String s 
    = (String)ViewState["Text"];
                    
    return ((s == null? String.Empty : s);
                }

                
    set
                {
                    ViewState[
    "Text"= value;
                }
            }

            
    internal static int _wordLength;

            [Description(
    "验证码长度")]
            
    public int WordLength
            {
                
    get { return LandpyIdentityControl._wordLength; }
                
    set
                {
                    LandpyIdentityControl._wordLength 
    = value;

                }
            }

            
    internal static string _value;

            [Description(
    "验证码内容")]
            
    public string Value
            {
                
    get { return LandpyIdentityControl._value; }
            }

            
    protected override void RenderContents(HtmlTextWriter output)
            {
                
    //output.Write(Text);           
            }

            
    public LandpyIdentityControl()
                : 
    base(HtmlTextWriterTag.Img)//重写父类的构造(输出流的HTML标记设置为图像类型)
            { }

            
    protected override void AddAttributesToRender(HtmlTextWriter writer)
            {
                
    base.AddAttributesToRender(writer);
                writer.AddStyleAttribute(HtmlTextWriterStyle.Cursor, 
    "pointer");
                writer.AddAttribute(
    "onclick""this.src='img.yy?id='+Math.random()");
                writer.AddAttribute(HtmlTextWriterAttribute.Src, 
    "img.yy");
                writer.AddAttribute(
    "alt""点击刷新");
            }
        }
    }

    下面是处理类:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Web;
    using System.Web.UI.WebControls;
    using System.Web.UI;
    using System.Web.SessionState;
    using System.Drawing;
    using System.IO;

    namespace Identify
    {
        
    public class LandpyHttpHander : IHttpHandler, IRequiresSessionState
        {
            
    /// <summary>
            
    /// 返回验证码字符
            
    /// </summary>
            
    /// <param name="codeCount">验证码长度</param>
            
    /// <returns></returns>
            private string GetRandomNumberString(int codeCount)
            {
                
    string strChoice = "2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,T,U,V,W,X,Y,Z";
                
    string[] strResult = strChoice.Split(new Char[] { ',' });
                
    string strReturn = "";
                Random rnd 
    = new Random();
                
    for (int i = 0; i < codeCount; i++)
                {
                    
    int j = rnd.Next(strResult.Length);
                    strReturn 
    = strReturn + strResult[j].ToString();
                }
                
    return strReturn;
            }

            
    private Color GetColor()
            {
                
    return Color.Black;
            }

            
    private Bitmap CreateImage(string str_AuthCode)
            {
                
    int width = str_AuthCode.Length * 21;
                
    int height = 30;
                Random rad 
    = new Random();
                Bitmap bmp 
    = new Bitmap(width, height);
                Graphics grp 
    = Graphics.FromImage(bmp);// 在图片上绘制图形
                grp.Clear(Color.LightGreen);
                grp.DrawRectangle(
    new Pen(Color.DarkGreen, 1), 00, width - 1, height - 1);
                
    //画图片的背景噪音线
                for (int i = 0; i < 15; i++)
                {
                    
    int x1 = rad.Next(width);
                    
    int x2 = rad.Next(width);
                    
    int y1 = rad.Next(height);
                    
    int y2 = rad.Next(height);

                    grp.DrawLine(
    new Pen(Color.Black), x1, y1, x2, y2);
                }
                
    //画图片的前景噪音点
                for (int i = 0; i < 100; i++)
                {
                    
    int x = rad.Next(width);
                    
    int y = rad.Next(height);

                    bmp.SetPixel(x, y, Color.Black);
                }
                Font f 
    = new Font("宋体"20, FontStyle.Bold);
                Brush br 
    = new SolidBrush(Color.Black);
                
    for (int i = 0; i < str_AuthCode.Length; i++)
                {
                    
    string s = str_AuthCode.Substring(i, 1);
                    Point p 
    = new Point(i * 20 + rad.Next(3), rad.Next(3+ 1);
                    grp.DrawString(s, f, br, p);
                }
                grp.Dispose();
                
    return bmp;

            }

            
    /// <summary>
            
    /// 是否可以处理远程的HTTP请求
            
    /// </summary>
            public bool IsReusable
            {
                
    get { return true; }
            }

            
    /// <summary>
            
    /// 将验证码图片发送给WEB浏览器
            
    /// </summary>
            
    /// <param name="context"></param>
            public void ProcessRequest(HttpContext context)
            {
                
    int size = LandpyIdentityControl._wordLength; //Int32.Parse((String)context.Session["Size"]);
                MemoryStream ms = new MemoryStream();
                
    string NumStr = GetRandomNumberString(size);
                LandpyIdentityControl._value 
    = NumStr;
                
    //context.Session.Add("value", NumStr);//将验证码字符保存到session里面
                Bitmap theBitmap = CreateImage(NumStr);
                theBitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
                context.Response.ClearContent();
                context.Response.ContentType 
    = "image/jpeg"//需要输出图象信息 要修改HTTP头为jpeg类型 
                context.Response.BinaryWrite(ms.ToArray()); 
                theBitmap.Dispose();
                ms.Close();
                ms.Dispose();
                context.Response.End();
            }

        }
    }

    其中验证码图片的生成随便copy了下,实际就是GDI+实现DrawString方法。如果对GDI+有了解相信会很容易理解的。

    这样“验证码”服务器控件就OK了,如果要使用,引入相应的Dll,设置下web.config,设置下控件的字符个数就可以使用了,很简单。

    在设计视图中,自定义服务器控件的属性可以赋初始值。比如我们的控件属性:

    [Description("验证码长度")]
            public int WordLength
            {
                get { return LandpyIdentityControl._wordLength; }
                set
                {
                    LandpyIdentityControl._wordLength = value;

                }
            }

    可以设置验证码的长度。

    另外,自定义控件是从WebControl继承,可以重写很多方法,比如RenderControl,RenderContents,AddAttributesToRender等,各个方法的作用可以查阅相关资料,本文不再说明。其中,对于UI来说RenderXXXX一系列方法是很重要的,如同Winfrom程序中的OnPrint方法一样。

    快去做自己喜欢的控件吧:)

    敬告

    作者:pangxiaoliang
    出处:http://www.cnblogs.com/pangxiaoliang
    本文版权归pangxiaoliang和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,谢谢合作。
  • 相关阅读:
    作业七随笔。。
    Jquery 图片走马灯效果原理
    参与招聘面试工作之简历与仪容篇
    无聊系列 C#中一些常用类型与java的类型对应关系
    关于ASP.NET MVC 中JsonResult返回的日期值问题
    最近参与招聘面试的工作总结
    Unix时间戳转日期时间格式,C#、Java、Python各语言实现!
    MVC 拦截器
    Python参考书籍(转载)
    PEP 8风格指南(转载)
  • 原文地址:https://www.cnblogs.com/pangxiaoliang/p/1512720.html
Copyright © 2011-2022 走看看