回 帖 发 新 帖 刷新版面

主题:[讨论]ASP.NET(C#)验证码控件图片无法显示的问题

在.NET2005中通过“文件”——“打开”——“网站”——“本地IIS“ 打开ASP.NET(C#)的网站项目,能正常运行页面,只是验证码控件的图片显示不了(显示一个红叉)。 

改用“文件系统”的形式打开并运行则可以正常显示。 

请问这个问题怎么解决? 

验证码控件代码如下: 
using System;
using System.Collections.Generic;
using System.ComponentModel;
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 AuthCode
{
    [ToolboxData("<{0}:AuthCode runat=server></{0}:AuthCode>")]
    public class AuthCode : WebControl
    {
        /// 〈summary>
        /// 获得验证码的值
        /// 〈/summary>
        /// 〈returns>验证码〈/returns>
        public string GetValue()
        {
            return HttpContext.Current.Session["value"].ToString();
        }
        [Bindable(true)]
        [Category("Appearance")]
        [Description("验证码字符长度")]
        [DefaultValue("ss")]
        [Localizable(true)]
        //长度
        internal static int mySize;

        public int MySize
        {
            get { return AuthCode.mySize; }
            set
            {
                AuthCode.mySize = value;

            }
        }


        public AuthCode()
            : base(HtmlTextWriterTag.Img)//重写父类的构造(输出流的HTML标记)
        { }
        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            base.AddAttributesToRender(writer);//将要输出的的HTML标签的属性和样式添加到指定的 HtmlTextWriter中
            writer.AddStyleAttribute(HtmlTextWriterStyle.Cursor, "pointer");//添加样式

            /**-
             * 图片的onclick事件 "this.src='VerifyImg.jd?id='+Math.random()"
             * 每次单击一次就有一个新的图片请求路径(VerifyImg.jd?id='+Math.random())参数只是
             * 告诉浏览器这是一个新的请求然后经过 IHttpHander处理生成新的图片 id 没有任何实际意思(创造一个新的请求)
             * -**/
            writer.AddAttribute("onclick", "this.src='img.jd?id='+Math.random()");//添加js VerifyImg.jd


            writer.AddAttribute(HtmlTextWriterAttribute.Src, "img.jd");
            writer.AddAttribute("alt", "点击刷新");
        }

    }

    public class AuthCodeHttpHander : 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 * 13;
            int height = 20;
            Random rad = new Random();
            Bitmap bmp = new Bitmap(width, height);
            Graphics grp = Graphics.FromImage(bmp);// 在图片上绘制图形
            grp.Clear(Color.White);//填充bmp的背景色
            grp.DrawRectangle(new Pen(Color.Red, 1), 0, 0, width - 1, height - 1);//绘制边框
            int num = width * height;
            for (int i = 0; i < num; i+=3)//在图片的指定坐标上画上有颜色的圆点
            {
                int x = rad.Next(width);
                int y = rad.Next(height);
                int r = rad.Next(255);
                int g = rad.Next(255);
                int b = rad.Next(255);
                Color c = Color.FromArgb(r, g, b);
                bmp.SetPixel(x, y, c);//在图片的指定坐标上画上有颜色的圆点
            }

            /*-------------------------- 在图片绘制字符串------------------------------------ */

            Font f = new Font("宋体", 12, 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 * 12 + 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 = AuthCode.mySize; //Int32.Parse((String)context.Session["Size"]);
            MemoryStream ms = new MemoryStream(); //  创建内存流(初始长度为0 自动扩充)
            string NumStr = GetRandomNumberString(size);// 获得验证码字符
            context.Session.Add("value", NumStr);//将验证码字符保存到session里面
            Bitmap theBitmap = CreateImage(NumStr);// 获得验证码图片
            theBitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);//将位图写入内存流
            context.Response.ClearContent();  //清除缓冲区里的所有内容输出
            context.Response.ContentType = "image/jpeg"; //需要输出图象信息 要修改HTTP头 
            context.Response.BinaryWrite(ms.ToArray()); //将内存流写入HTTP输出流
            theBitmap.Dispose(); //释放资源
            ms.Close();//释放资源
            ms.Dispose();//释放资源
            context.Response.End();
        }


    }

}


我是这样用的这个验证码控件的: 

1:修改web.config 
在 <system.web> </system.web>间加入下面的代码: 

    <httpHandlers>
    <add verb="*" path="*.jd" type="AuthCode.AuthCodeHttpHander" />
    </httpHandlers>

2: 
开始——运行——cmd 
cd C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 

csc /target:library AuthCode.cs 

将得到的DLL文件添加到项目的引用中,在工具栏中右键点“选择项”——在.net组件中勾选“AuthCode”,将这个控件拖到页面中使用的。 在起属性中设置MySize即验证码的长度。
例如:
<cc1:AuthCode ID="AuthCode1" runat="server" MySize="4"  />

我使用这个控件的方法上面说的比较详细了,有人能找到我的问题么,我实在找不出来。

回复列表 (共2个回复)

沙发

public void ProcessRequest(HttpContext context)
        {
            int size = AuthCode.mySize; //Int32.Parse((String)context.Session["Size"]);
            MemoryStream ms = new MemoryStream(); //  创建内存流(初始长度为0 自动扩充)
            string NumStr = GetRandomNumberString(size);// 获得验证码字符
            context.Session.Add("value", NumStr);//将验证码字符保存到session里面
            Bitmap theBitmap = CreateImage(NumStr);// 获得验证码图片
            theBitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);//将位图写入内存流
            context.Response.ClearContent();  //清除缓冲区里的所有内容输出
            context.Response.ContentType = "image/jpeg"; //需要输出图象信息 [color=FF0000]要修改HTTP头 [/color]
            context.Response.BinaryWrite(ms.ToArray()); //将内存流写入HTTP输出流
            theBitmap.Dispose(); //释放资源
            ms.Close();//释放资源
            ms.Dispose();//释放资源
            context.Response.End();
        }
我今天偶然发现IIS里有修改HTTP头的设置,而且上面的程序注释中提到了要修改HTTP头。
那么,HTTP头名和值该改成什么呢?

板凳

<httpHandlers> 设置由应用程序子目录继承。

<add> 指令按由上而下的顺序进行处理。如果两个或多个 <add> 元素指定相同的谓词/路径组合,则最后一个 <add> 会重写其他所有元素。

Microsoft Internet 信息服务 (IIS) 有自己的 ISAPI 映射扩展模型。为使给定应用程序扩展与其处理程序之间的映射生效,该扩展必须在 IIS 中映射为 ASP.NET ISAPI。对于自定义扩展等非标准扩展,则必须相应地配置 IIS。

http://msdn.microsoft.com/zh-cn/library/bya7fh0a(VS.85).aspx

又找到一个影响因素,MSDN中搜到的。关于“<httpHandlers> ”的“<add>”。





    <httpHandlers>
    <add verb="*" path="*.jd" type="AuthCode.AuthCodeHttpHander" />
    </httpHandlers>
可能是这个映射在IIS里没有,所以显示不了。我试过在IIS里加映射,没成功。

我来回复

您尚未登录,请登录后再回复。点此登录或注册