我有两个页面login.aspx(登陆页面)和code.aspx(生成随机码的页面),现在呢我在code页面生成了随机码也在login页面上显示了,但是我在比较login上的随机码和code里生成的随机码时(我把code里生成的随机码存放在了session里),session里的值总是和login上显示的随机码不一致,准确的说是session存的值总是比login看到的随机码慢一次,这是怎么回事?
下面的code页面生成随机码的代码
    private string CreateCheckCodeString()
    { //定义用于验证码的字符数组
        char[] AllCheckCodeArray ={ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
        //定义验证码字符串
        string randomcode = "";
        Random rd = new Random();
        //生成4位验证码字符串
        for (int i = 0; i < 4; i++)
        {
            randomcode += AllCheckCodeArray[rd.Next(AllCheckCodeArray.Length)];
        }
        Session["randomcode"] = randomcode;//(这里我把随机码存放在了session里)
        return randomcode;
    }
    //生成验证码图片
    protected void Page_Load(object sender, EventArgs e)
    {
        //定义图片的宽度
        int ImageWidth = 55;
        //定义图片高度
        int ImageHeigh = 22;
        //定义字体,用于绘制文字
        Font font = new Font("Arial", 12, FontStyle.Bold);
        //定义画笔,用于绘制文字
        Brush brush = new SolidBrush(Color.Black);
        //定义钢笔,用于绘制干扰线
        Pen pen1 = new Pen(Color.FromArgb(255, 100, 100), 0);//这里也可以直接获得一个现有的color对象如:Color.Gold.我是为了美观所以定义和下面一样
        Pen pen2 = new Pen(Color.FromArgb(255, 100, 100), 0);//这里根据ARGB值定义获得了一个color对象
        //创建一个图像
        Bitmap BitImage = new Bitmap(ImageWidth, ImageHeigh);
        //从图像获取一个绘画面
        Graphics graphics = Graphics.FromImage(BitImage);
        //清除整个绘图画面并用颜色填充
        graphics.Clear(ColorTranslator.FromHtml("#F0F0F0"));//这里从HTML代码获取color对象
        //定义文字的绘制矩形区域
        RectangleF rect = new RectangleF(5, 2, ImageWidth, ImageHeigh);
        //定义一个随机数对象,用于绘制干扰线
        Random rand = new Random();
        //生成两条横向的干扰线
        for (int i = 0; i < 2; i++)
        {
            //定义起点
            Point p1 = new Point(0, rand.Next(ImageHeigh));
            //定义终点
            Point p2 = new Point(ImageWidth, rand.Next(ImageHeigh));
            //绘制直线
            graphics.DrawLine(pen1, p1, p2);
        }
        //生成两条纵向的干扰线
        for (int i = 0; i < 2; i++)
        {
            //定义起点
            Point p1 = new Point(rand.Next(ImageWidth), 0);
            //定义终点
            Point p2 = new Point(rand.Next(ImageWidth), ImageHeigh);
            //绘制直线
            graphics.DrawLine(pen2, p1, p2);
        }
        //绘制验证码文字
        graphics.DrawString(CreateCheckCodeString(), font, brush, rect);
        //保存图片为gif格式
        BitImage.Save(Response.OutputStream, ImageFormat.Gif);
        //释放对象
        graphics.Dispose();
        BitImage.Dispose();
    }急!!!谢谢了!

解决方案 »

  1.   

    是不是在取session码的时候,codex重新又生成过一次呢()....
      

  2.   

    我刚刚试了一下。
    我是用一个按钮,点击按钮的时候,把session的值 response.write显示出来,发现是点击按钮的时候页面又刷新了一遍,所以看的验证码不一样。
    我想你的情况也是一样的。应该是页面刷新造成的两者不一致的。
      

  3.   

    不能真接写在Page_Load(object sender, EventArgs e)里面
    要不然每次提交在服务器端都会重新生成
    起码要用个if(!IsPostBack){}
    框起来
      

  4.   

    起码要用个if(!IsPostBack){} 
    框起来 Session["randomcode"] =CreateCheckCodeString();
      

  5.   

    谢谢大家!可是问题还是没有解决。。我现在急=着用,可是查找了很多资料也没得到结果,哪位高手能帮忙给个解决方法?怎么存session的值才能保证在login页面读出来的session和验证码图片上显示的一样呢?
      

  6.   

    你的两个aspx之间是个什么样的运行关系?我想你是把Code.aspx作为一个可下载图片嵌入login.aspx中了。在ie等浏览器上,图片都是异步地下载的,因此code.aspx在login.aspx之后才被访问。我不知道“我在比较login上的随机码和code里生成的随机码时”的说法具体是怎样比较,有没有实际的逻辑意义。从程序数据处理角度看,首先是login.aspx显示,之后code.aspx才被访问并更新了session中的值,此时login.aspx再次回发(后台处理时)就可以看到前一个code.aspx被访问时生成的验证码并比较用户录入的是否正确。如果这个回发不是重定向到其它页面,而是login.aspx页面再次显示在客户端,那么紧接着code.aspx又被从客户端访问一次,因此session中的值又被更新了。在这个过程中,“比较用户录入的验证码是否正确”的那个时间点恰好可以正确地比较用户的录入,因为这里需要在login.aspx中比较的session值是上一次code.aspx生成的验证。而如果你在login.aspx中去打印session的值,然后再用眼睛去看客户端上显示验证码,仔细看上面的流程,你看到的肯定是后一个验证码嘛。
      

  7.   

    我不知道你是怎么实现的。一般的做法是:在你的Login.aspx页面里面放一个image,这个image的src指向code.aspx。当login.aspx页面打开时image里面的图像也显示出来,并且保存在服务器的Session里,login.aspx回发的时候验证用户输入的和Session里面保存的即可。在这个过程中code.aspx页面只被GET一次,是不会出现再次生成。
      

  8.   

    如果你要逻辑上简单点,那么就把 CreateCheckCodeString() 方法放到login.aspx 的 Page_PreRender 中去。5楼提到“不能写在page_load”中是对的,可惜没有说出来如果不写在page_load中那么应该写在哪里。这样,你在login.aspx在调用 CreateCheckCodeString 之后打印、跟踪到的验证码跟在客户端用眼睛看到的验证码就同步了。
      

  9.   

    大家说的没错,估计是楼主对页面的生命周期不熟悉
    建议使用.ashx可以提高效率
      

  10.   

    我猜你在问题中贴出的代码是网上抄来的,还没有理解它。许多此类“范例”都是在显示图像的aspx中更新到session,那么显然你在login.aspx中任何地方读到的验证码值都跟你随后在客户端屏幕上用眼睛看到的不一致,读它的程序逻辑就决定了一定有这个差别。
      

  11.   

    当然啦,在图像aspx中生成session有它的一定的好处,当你没有ajax技术而又要login.aspx上实现“换一个验证码”功能时,直接使用javascript来动态地刷新一下图片src地址( 例如:var img.src="code.aspx?"+GetTime() )就可以。而如果在login.aspx中计算验证码,code.aspx只是显示验证码图片,那么这个功能就需要使用ajax实现才能让图片变化。
      

  12.   

    你在传值的时候最好加上时间因为当你传相同值的时候,它存进session的值是一样的我想你也试过只要后面加上时间就不会出现这种情况了
      

  13.   

    加了if(!IsPostBack){} 框起来后.在login.aspx的Button事件里 if(string.Compare(Session["randomcode"].ToString(),this.Vaildate.Text,true)!=0)去判断不就可以了么??估计你Page_Load走了2次..一般网上的都这样...
      

  14.   

    可以这样实现...
    using System;
    using System.Configuration;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Xml.Linq;
    using System.IO;public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {     
            this.getJpg();
        }
        //将验证码画在图像上
        protected void getJpg()
        { 
            //定义一个长度
            int length = 6;
            //创建一个图像
            Bitmap Bit = new Bitmap(120, 40);
            //创建一个绘图图像
            Graphics g = Graphics.FromImage(Bit);
            //调用getLength()方法来获取图像中显示的验证码
            string strcheck = this.getLength(length);
            //为图像添加背景色
            g.Clear(Color.DarkGreen);
            //图像中验证码显示的字体与大小
            Font f = new Font("@Batang",20);
            //文本的布局,此处为空,默认布局
            StringFormat SF = new StringFormat();
            //在指定的区域绘制字符串
            g.DrawString(strcheck, f, Brushes.Orange, 1f, 1f, SF);
            //为背景随机添加横线,为了不让横线重复,取了时间的毫秒部分
            Random R = new Random(DateTime.Now.Millisecond);        for (int i = 0; i < 10; i++)
            {
                int y = R.Next(Bit.Height);            g.DrawLine(new Pen(Color.Black,0), 0, y, Bit.Width, y);
            }
            //创建一个存取流,需要倒包using System.IO
            MemoryStream MS = new MemoryStream();
            //将图像以Jpg的格式保存到MS流中
            Bit.Save(MS, System.Drawing.Imaging.ImageFormat.Jpeg);
            //将二进制字符串写入到Http输出流
            this.Response.BinaryWrite(MS.ToArray());
           
        }    //得到验证码的数字
        private string getLength(int strlength)
        {
            //自定义一个字符串
            string str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
            //定义一个空的字符串,以保存验证码数字
            string str1 = "";
            //随机生成数字,取时间毫秒部分是为了不让数字重复
            Random RD = new Random(DateTime.Now.Millisecond);        for (int i = 0; i < strlength; i++)
            {
                str1 += str[RD.Next(0,61)];//在0-61之间取数                   
            }        return str1;//返回得到的验证码
        }
    }  最后结果:
      

  15.   

    我曾经也遇见这种情况,就是在点 button时又生成了一次
      

  16.   

    好像是asp.net 的生命周期问题,page_load在控件image之前被执行了,此时还没有生成图片,也没有调用生成随机数的方法来生成字符串。
      

  17.   

    哈哈,我明白了
    在login.aspx中创建一个session为null
    然后在code.aspx中将验证码的值赋给session
    我们就能取到login.aspx中session的值了
    这样每次就是新的了