以前有过一篇文章是动态生成
验证码的例子,这里再补充一点,因为很多东西例子跟实际应用还是有很大的区别,你会碰到一些意想不到的问题。例如,最近我用到的验证码类(checkcode.aspx.cs):
程序代码
而我的checkcode.aspx代码是下面这样的。
程序代码
原来一直没有发现什么不妥当,不过在5dblog公测试的时候,发现了一些问题,就是IE的缓存问题,当然当我知道这个的时候我应该批评我当初的不细心,这应该是一个基本的东西, asp.net 2.0提供了那么好的缓存机制,特别是局部缓存,真的很重要,不过这里我们不是局部缓存,而是不缓存整个页面,在我的理解中不申明缓存,默认的应该是不缓存的的,不过事实不象我想象的那么样。
对于上个问题我只是对checkcode.aspx作个个小改动:
在<%@ Page language=" c#" Inherits="_5dblog.CheckCode" CodeFile="CheckCode.aspx.cs" %>下面加上:<%@ OutputCache Duration="1" varybyparam="none" Location= "None" %>
不过感觉Duration="1"好象是多余的,去掉应该行吧。
另外有一种方法是把生成验证码的页面带一个随即参数,例如:checkcode.aspx?count=随即数 <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script>

using
System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace _5dblog
{
/// <summary>
/// CheckCode 的摘要说明:用于验证码的生成!
/// </summary>
public partial class CheckCode : System.Web.UI.Page
{
protected void Page_Load( object sender, System.EventArgs e)
{
this .CreateCheckCodeImage(GenerateCheckCode());
// 在此处放置用户代码以初始化页面
}
#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base .OnInit(e);
}
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
}
#endregion
private string GenerateCheckCode()
{
int number;
char code;
string checkCode = String.Empty;
System.Random random = new Random();
for ( int i = 0 ; i < 4 ; i ++ )
{
number = random.Next();
// if(number % 2 == 0)
code = ( char )( ' 0 ' + ( char )(number % 10 ));
// else
// code = (char)('A' + (char)(number % 26));
checkCode += code.ToString();
}
System.Web.HttpContext.Current.Session.Add( " CheckCode " , checkCode);
return checkCode;
}
private void CreateCheckCodeImage( string checkCode)
{
if (checkCode == null || checkCode.Trim() == String.Empty)
return ;
System.Drawing.Bitmap image = new System.Drawing.Bitmap( checkCode.Length * 12 , 20 );
Graphics g = Graphics.FromImage(image);
try
{
// 生成随机数生成器
Random random = new Random();
// 清空图片背景色
g.Clear(Color.White);
// 画图片的背景噪音线
for ( int i = 0 ; i < 25 ; i ++ )
{
int x1 = random.Next(image.Width);
int x2 = random.Next(image.Width);
int y1 = random.Next(image.Height);
int y2 = random.Next(image.Height);
g.DrawLine( new Pen(Color.Silver), x1, y1, x2, y2);
}
Font font = new System.Drawing.Font( " Arial " , 12 , (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic));
System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush( new Rectangle( 0 , 0 , image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2f , true );
g.DrawString(checkCode, font, brush, 2 , 2 );
// 画图片的前景噪音点
for ( int i = 0 ; i < 100 ; i ++ )
{
int x = random.Next(image.Width);
int y = random.Next(image.Height);
image.SetPixel(x, y, Color.FromArgb(random.Next()));
}
// 画图片的边框线
g.DrawRectangle( new Pen(Color.Silver), 0 , 0 , image.Width - 1 , image.Height - 1 );
System.IO.MemoryStream ms = new System.IO.MemoryStream();
image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
Response.ClearContent();
Response.ContentType = " image/Gif " ;
Response.BinaryWrite(ms.ToArray());
}
finally
{
g.Dispose();
image.Dispose();
}
}
}
}
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace _5dblog
{
/// <summary>
/// CheckCode 的摘要说明:用于验证码的生成!
/// </summary>
public partial class CheckCode : System.Web.UI.Page
{
protected void Page_Load( object sender, System.EventArgs e)
{
this .CreateCheckCodeImage(GenerateCheckCode());
// 在此处放置用户代码以初始化页面
}
#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base .OnInit(e);
}
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
}
#endregion
private string GenerateCheckCode()
{
int number;
char code;
string checkCode = String.Empty;
System.Random random = new Random();
for ( int i = 0 ; i < 4 ; i ++ )
{
number = random.Next();
// if(number % 2 == 0)
code = ( char )( ' 0 ' + ( char )(number % 10 ));
// else
// code = (char)('A' + (char)(number % 26));
checkCode += code.ToString();
}
System.Web.HttpContext.Current.Session.Add( " CheckCode " , checkCode);
return checkCode;
}
private void CreateCheckCodeImage( string checkCode)
{
if (checkCode == null || checkCode.Trim() == String.Empty)
return ;
System.Drawing.Bitmap image = new System.Drawing.Bitmap( checkCode.Length * 12 , 20 );
Graphics g = Graphics.FromImage(image);
try
{
// 生成随机数生成器
Random random = new Random();
// 清空图片背景色
g.Clear(Color.White);
// 画图片的背景噪音线
for ( int i = 0 ; i < 25 ; i ++ )
{
int x1 = random.Next(image.Width);
int x2 = random.Next(image.Width);
int y1 = random.Next(image.Height);
int y2 = random.Next(image.Height);
g.DrawLine( new Pen(Color.Silver), x1, y1, x2, y2);
}
Font font = new System.Drawing.Font( " Arial " , 12 , (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic));
System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush( new Rectangle( 0 , 0 , image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2f , true );
g.DrawString(checkCode, font, brush, 2 , 2 );
// 画图片的前景噪音点
for ( int i = 0 ; i < 100 ; i ++ )
{
int x = random.Next(image.Width);
int y = random.Next(image.Height);
image.SetPixel(x, y, Color.FromArgb(random.Next()));
}
// 画图片的边框线
g.DrawRectangle( new Pen(Color.Silver), 0 , 0 , image.Width - 1 , image.Height - 1 );
System.IO.MemoryStream ms = new System.IO.MemoryStream();
image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
Response.ClearContent();
Response.ContentType = " image/Gif " ;
Response.BinaryWrite(ms.ToArray());
}
finally
{
g.Dispose();
image.Dispose();
}
}
}
}
而我的checkcode.aspx代码是下面这样的。

<%
@ Page language
=
"
c#
"
Inherits
=
"
_5dblog.CheckCode
"
CodeFile
=
"
CheckCode.aspx.cs
"
%>
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
< HTML >
< HEAD >
< title > CheckCode </ title >
< meta content ="Microsoft Visual Studio .NET 7.1" name ="GENERATOR" >
< meta content ="C#" name ="CODE_LANGUAGE" >
< meta content ="JavaScript" name ="vs_defaultClientScript" >
< meta content ="http://schemas.microsoft.com/intellisense/ie5" name ="vs_targetSchema" >
</ HEAD >
< body >
< form id ="Form1" method ="post" runat ="server" >
< FONT face ="宋体" ></ FONT >
</ form >
</ body >
</ HTML >
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
< HTML >
< HEAD >
< title > CheckCode </ title >
< meta content ="Microsoft Visual Studio .NET 7.1" name ="GENERATOR" >
< meta content ="C#" name ="CODE_LANGUAGE" >
< meta content ="JavaScript" name ="vs_defaultClientScript" >
< meta content ="http://schemas.microsoft.com/intellisense/ie5" name ="vs_targetSchema" >
</ HEAD >
< body >
< form id ="Form1" method ="post" runat ="server" >
< FONT face ="宋体" ></ FONT >
</ form >
</ body >
</ HTML >
原来一直没有发现什么不妥当,不过在5dblog公测试的时候,发现了一些问题,就是IE的缓存问题,当然当我知道这个的时候我应该批评我当初的不细心,这应该是一个基本的东西, asp.net 2.0提供了那么好的缓存机制,特别是局部缓存,真的很重要,不过这里我们不是局部缓存,而是不缓存整个页面,在我的理解中不申明缓存,默认的应该是不缓存的的,不过事实不象我想象的那么样。
对于上个问题我只是对checkcode.aspx作个个小改动:
在<%@ Page language=" c#" Inherits="_5dblog.CheckCode" CodeFile="CheckCode.aspx.cs" %>下面加上:<%@ OutputCache Duration="1" varybyparam="none" Location= "None" %>
不过感觉Duration="1"好象是多余的,去掉应该行吧。
另外有一种方法是把生成验证码的页面带一个随即参数,例如:checkcode.aspx?count=随即数 <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script>