对 asp.net 提供的 Login 控件进行扩展,在密码后面加一图文验证功能以防止自动注册程序。
1.添加页面 imageValidate.aspx,该页面是生成验证码的页面
在头部添加信息:
<% Response.Buffer = true ;%>
<% Response.ExpiresAbsolute = DateTime.Now.AddSeconds(-1);%>
<% Response.Expires = 0 ;%>
<% Response.CacheControl = "no-cache" ; %>
PS:
①Response.Buffer 属性指示是否缓冲页输出。当缓冲页输出时(true),只有当前页的所有服务器脚本处理完毕或者调用了 Flush 或 End 方法后,服务器才将响应发送给客户端。服务器将输出发送给客户端后就不能再设置 Buffer 属性。因此,应该在 .asp 文件的第一行调用 Response.Buffer 。
② Response.ExpiresAbsolute属性指定缓存于浏览器中的页的到期日期和时间。在未到期之前,若用户返回到该页,该缓存的页就显示。如果未指定时间,该主页在当天午夜到期。如果指定日期,则该主页在脚本运行当天的指定时间到期。
③DateTime.Now.AddSeconds(-1);得到系统时间后,减少1秒得到一个时间值。
④Response.Expires 属性指定了在浏览器上缓冲存储的页距过期还有多少分钟。如果用户在某个页过期之前又回到此页,就会显示缓冲区中的版本,将此参数设置为 0 可使缓存的页立即过期。
⑤Response.CacheControl决定代理服务器是否能缓存 ASP 生成的输出,其参数可有以下几种:
在 imageValidate.aspx.cs 中的代码如下:
protected void Page_Load(object sender, EventArgs e)
{
CreateCheckCodeImage(GenerateCheckCode()); //生成 4 位的验证码
}
private void CreateCheckCodeImage(string checkCode) // 生成 4 位的验证码
{
if (checkCode == null || checkCode.Trim() == String.Empty)
return;
System.Drawing.Bitmap image = new System.Drawing.Bitmap((int)Math.Ceiling((checkCode.Length * 12.5)), 22);
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();
}
}
private string GenerateCheckCode()
{
int number;
char code;
string checkCode = String.Empty;
System.Random random = new Random();
for(int i=0;i<5;i++)
{
number = random.Next();
if (number % 2 == 0)
code = (char)('0' + (char)(number % 10));
else
code = (char)('A' + (char)(number % 26));
checkCode += code.ToString();
}
Session["CheckCode"] = checkCode;
return checkCode;
}
PS:
①Random 类
表示伪随机数生成器,这是一种能够产生满足某些随机性统计要求的数字序列的设备。
表示伪随机数生成器,这是一种能够产生满足某些随机性统计要求的数字序列的设备。
Random类方法
②Session对象
可以在 Session 对象中存储值。存储在 Session 对象中的信息在会话及会话作用域内有效。
③ System.Drawing.Bitmap
用c#做图形图像处理的时候需要用到System.Drawing.Bitmap。
重载列表
Bitmap公共属性
Bitmap方法
④Math.Ceiling
Math.Ceiling 返回大于或等于指定数字的最小整数。
⑤Graphics类
封装一个 GDI+ 绘图图面。 此类不能被继承。
Graphics方法
⑥Pen 类
定义用于绘制直线和曲线的对象。无法继承此类。
⑦Font类
定义特定的文本格式,包括字体、字号和样式特性。 此类不能被继承。
Font构造方法
⑧FontStyle 枚举
指定应用于文本的样式信息。
成员
⑨LinearGradientBrush 类
使用线性渐变绘制区域。
⑩Color.FromArgb 方法
基于四个 8 位 ARGB 分量(alpha、红色、绿色和蓝色)值创建 Color 结构。
⑪MemoryStream 类
创建一个流,其后备存储为内存。
MemoryStream方法
⑫Response.ClearContent()方法
清除缓冲区流中的所有内容输出。
⑬Response.ContentType()方法
ContentType 属性指定响应的 HTTP 内容类型。如果未指定 ContentType,默认为 text/HTML。
⑭Response.BinaryWrite()方法
在不进行字符转换的情况下直接向输出写数据。
2. 添加页面 LoginImageValidate.aspx。
该页面将使用此验证码。首先,拖拽一个 login 控件到页面中,将之“转换为模板”,在 Html 源文件中,表格中密码那行后面,“下次记住我”那行之前,添加如下代码:
<tr>
<td align="right">
<asp:Label ID="Label1" runat="server" AssociatedControlID="Password">验证码:</asp:Label>
</td>
<td>
<asp:ImageButton ID="imgValid" ImageUrl="~/imageValidate.aspx" runat="server" Height="16px" Width="106px" />
<asp:TextBox ID="txtImgValid" runat="server" Font-Size="0.8em"></asp:TextBox>
</td>
</tr>
其中 ImageUrl="imageValidate.aspx“ 的 imageValidate.aspx 指的就是我们第一步建立的文件。
3.在 login 控件的 authenticate 事件中加入代码
protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
{
TextBox txtIamge = Login1.FindControl("txtImgValid") as TextBox;
if(Session["CheckCode"]==null)
{
Response.Write("<script language='JavaScript'>alert('未可知错误!')</script>"); //弹出提示窗口
e.Authenticated = false;
return;
}
if(String.Compare(Session["CheckCode"].ToString(),txtIamge.Text,true)!=0)
{
Response.Write("<script language='javascript'>alert('不匹配!')</script>"); //弹出提示窗口
e.Authenticated = false;
return;
}
e.Authenticated = true;
}
PS:
①Login.Authenticate 事件
验证用户的身份后出现。
②Page.FindControl 方法
②Page.FindControl 方法
在页命名容器中搜索指定的服务器控件。
③Response 对象
使用 Response 对象可以将输出发送到客户端。
使用 Response 对象可以将输出发送到客户端。
Response.Write("<script language='JavaScript'>alert('未可知错误!')</script>") //弹出提示窗口
④事件参数 AuthenticateEventArgs.Authenticated
Login 控件作为登陆界面,响应其 Authentication 事件,若逻辑判断登录成功,则设置Authenticated属性为true,进行页面之间的跳转。