学习笔记---验证控件

作为程序员, 永远别指望用户按照规则进行输入, 比较理想的状况是在客户端浏览器和服务器端进行双重验证. 通常在客户端浏览器进行非功能性的常规验证, 如: 非空验证、范围验证及输入格式验证等, 而在服务器端进行功能性验证, 如: 检查账户是否存在, 检查用户权限等. 客户端浏览器的验证一般通过JavaScript实现, 验证过程与服务器无关, 在客户端浏览器验证通过后, 才将请求参数发送到服务器, 由服务端再次进行验证.微软的ASP.NET验证框架实现了客户端浏览器和服务器的双重验证.

 

1. IValidator接口: ---ErrorMessage属性、IsValid属性、Validate()方法
验证控件的核心是IValidator接口(System.Web.UI下), 其中有三个重要的成员: ErrorMessage属性、IsValid属性及Validate()方法, 执行validate方法后, 将设置IsValid属性.

 

2. BaseValidator抽象类:
为方便使用, ASP.NET通过实现了IValidator接口的抽象类BaseValidator为我们提供了大量的属性和方法.其中比较重要的属性有:
ErrorMessage: 设置错误信息.
IsValid: 验证结果.
ControlToValidate: 对那个控件进行验证(通过ID查找)
Display: 错误信息的显示方式, 有static、dynamic、none三中, static提前占位, 而dynamic不提前占位; none表示不在验证控件中显示, 通常配合BaseValiddator的Text属性, 将错误信息显示在ValidationSummary中.
Text: 如果设置了Text, 验证控件将只显示Text内容, 而ErrorMessage的信息将放到ValidationSummary中显示.
ValidationGrop: 只验证同一组的页面对象, 建议一开始就设置好分组.
EnableClientScript: 是否启用客户端验证
SetFocusOnError: 自动将焦点移到未通过验证的空间内.

 

3. ASP.NET验证控件:
RequiredFieldValidator: 检查用户是否输入, 除此控件外, 其他控件无输入时将默认不检查, 直接通过.
RegularExpressionValidator: 使用正则表达式进行输入内容的验证.
    正则表达式内容:
    元数据: a
    [a,b,c]: abc任选一个, 如果可选项很多, 可用[a-z]
    \w: 大写字母、小写字母、0-9;   \W: 非大写字母、小写字母和0-9之外的字符;   \w\W: 所有字符
    \d: 0-9;   \D: 非0-9的字符
    \s: 空白
    数量词: ?表示0-1个;   +表示1-n个;   *表示0-n个;  {m,n}表示最少m个, 最多n个
    (): 分组
CompareValidator: 用来比较两个绑定控件的内容. 需要通过Operator指定比较方式, 还需要通过Type指定比较的数据类型.
RangeValidator: 判断内容是否在指定范围, 通过MaximumValue和MinimumValue指定最大和最小值, 也需要通过Type指定数据类型.
CustomValidator: 自定义验证, 既可以在客户端浏览器验证也可以在服务器验证.客户端验证需要通过ClientValidationFunction属性设置验证用的JavaScript脚本函数名, 服务器端验证需要通过控件的ServerValidate事件来完成.
    .aspx文件中, 客户端浏览器验证的JavaScript脚本函数的形式如下:
    function ClientValidate(source,clientside_arguments)
    {

    }
    .cs文件中, 服务器端验证时ServerValidate事件的处理方法, 验证结果需要通过参数args.IsValid属性向验证框架返回结果, args.IsValid默认true;
    protected void ServerValidate(object source, ServerValidateEventArgs args)
    {

    }
ValidationSummary: 收集页面上的验证信息并统一显示, 还可以通过ValidationGroup属性显示一组验证信息.
注意: 按钮上有一个默认开启的属性CausesValidation, 表示该按钮是否激发验证, 如果该按钮通被包含在同一个ValidationGroup中, 则只进行该组中控件的验证.

 

4. 服务器端验证的时机:
页面对象有11个事件, 有两个非常重要的时间点(博客里有那张图): 一个是在Page_InitComplete --- Page_PreLoad之间, 完成控件的视图状态的读取以及请求参数到控件属性的赋值操作; 第二个是在Page_Load --- Page_LoadComplete之间, 完成服务器端请求参数处理和控件事件登记、通过页面对象的Validate()方法验证控件, 并通过其IsValid属性获得结果、控件事件的执行.
服务器端验证时通过ServerValidate事件来完成的, 所以验证时机是在Page_Load事件之后, 控件事件之前执行. 页面上会有一个验证控件集合Page.Validators, 当执行服务器验证时, 遍历该集合, 改变页面对象的IsValid属性. 如果我们希望提前验证, 需要手动调用this.Validate()方法.

 

//default.aspx代码

代码
 
   
<% @ Page Language = " C# " AutoEventWireup = " true " CodeFile = " Default.aspx.cs " Inherits = " _Default " %>

<! DOCTYPE html PUBLIC " -//W3C//DTD XHTML 1.0 Transitional//EN " " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd " >

< html xmlns = " http://www.w3.org/1999/xhtml " >
< head runat = " server " >
< title > Untitled Page </ title >
< style type = " text/css " >
.style1
{
width:
95 % ;
height: 216px;
}
.style5
{
}
.style6
{
width: 57px;
}
</ style >
</ head >
< body >
< form id = " form1 " runat = " server " >
< div style = " text-align:center; " >
< div style = " width: 500px; height:500px; background-color:Silver; text-align:left; margin-top: 20; padding: 10px 0px 0px 30px; margin-top:4% " >

< table class = " style1 " >
< tr >
< td class = " style6 " >
< label for = " txt_username " > 用户名: </ label >
</ td >
< td class = " style5 " >
< asp:TextBox ID = " txt_username " runat = " server " Width = " 209px " ></ asp:TextBox >
</ td >
< td >
< asp:RequiredFieldValidator ID = " validator_rqeField_username " runat = " server "
ControlToValidate
= " txt_username " Display = " Dynamic " ErrorMessage = " 用户名不能为空 " ></ asp:RequiredFieldValidator >
< asp:CustomValidator ID = " validator_custom_username " runat = " server "
ErrorMessage
= " 用户名已存在 " ControlToValidate = " txt_username " ></ asp:CustomValidator >
</ td >
</ tr >
< tr >
< td class = " style6 " >
< label for = " txt_password " > 密 码: </ label >
</ td >
< td class = " style5 " >
< asp:TextBox ID = " txt_password " runat = " server " Width = " 209px " TextMode = " Password " ></ asp:TextBox >
</ td >
< td >
< asp:RequiredFieldValidator ID = " validator_rqeField_password " runat = " server "
ControlToValidate
= " txt_password " ErrorMessage = " 密码不能为空 " ></ asp:RequiredFieldValidator >
</ td >
</ tr >
< tr >
< td class = " style6 " >
< label for = " txt_confirm " > 确 认: </ label >
</ td >
< td class = " style5 " >
< asp:TextBox ID = " txt_confirm " runat = " server " Width = " 209px " TextMode = " Password " ></ asp:TextBox >
</ td >
< td >
< asp:RequiredFieldValidator ID = " validator_rqe_confirm " runat = " server "
Display
= " Dynamic " ErrorMessage = " 确认密码不能为空 " ControlToValidate = " txt_confirm " ></ asp:RequiredFieldValidator >
< asp:CompareValidator ID = " validator_compto_conpass " runat = " server "
ControlToCompare
= " txt_password " ControlToValidate = " txt_confirm "
Display
= " Dynamic " ErrorMessage = " 密码不一致 " ></ asp:CompareValidator >
</ td >
</ tr >
< tr >
< td class = " style6 " >
< label for = " txt_email " > 邮 箱: </ label >
</ td >
< td class = " style5 " >
< asp:TextBox ID = " txt_email " runat = " server " Width = " 209px " ></ asp:TextBox >
</ td >
< td >
< asp:RequiredFieldValidator ID = " validator_rqeField_email " runat = " server "
ControlToValidate
= " txt_email " Display = " Dynamic " ErrorMessage = " 邮箱不能为空 " ></ asp:RequiredFieldValidator >
< asp:RegularExpressionValidator ID = " validator_regx_email " runat = " server "
ControlToValidate
= " txt_email " Display = " Dynamic " ErrorMessage = " 邮件格式错误 "
ValidationExpression
= " \w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* " ></ asp:RegularExpressionValidator >
</ td >
</ tr >
< tr >
< td class = " style6 " >
< label for = " txt_birth " > 生 日: </ label >
</ td >
< td class = " style5 " >
< asp:TextBox ID = " txt_birth " runat = " server " Width = " 209px " ></ asp:TextBox >
</ td >
< td >
< asp:RangeValidator ID = " validator_range_birth " runat = " server "
ControlToValidate
= " txt_birth " ErrorMessage = " 日期格式错误 " Type = " Date " ></ asp:RangeValidator >
</ td >
</ tr >
< tr >
< td class = " style6 " >
验证码:
</ td >
< td class = " style5 " colspan = " 2 " >
< asp:Image ID = " Image1 " runat = " server " ImageUrl = " ~/DynamicCode.ashx " />
</ td >
</ tr >
< tr >
< td class = " style6 " >
输入验证码:
</ td >
< td class = " style5 " colspan = " 2 " >
< asp:TextBox ID = " txt_dcode " runat = " server " Width = " 210px " ></ asp:TextBox >
< asp:RequiredFieldValidator ID = " RequiredFieldValidator1 " runat = " server "
ErrorMessage
= " 验证码不能为空 " Display = " Dynamic " ControlToValidate = " txt_dcode " ></ asp:RequiredFieldValidator >
< asp:CustomValidator ID = " Validator_Dcode " runat = " server "
ErrorMessage
= " 验证码错误 " ControlToValidate = " txt_dcode " Display = " Dynamic "
onservervalidate
= " Validator_Dcode_ServerValidate " ></ asp:CustomValidator >
</ td >
</ tr >
< tr >
< td colspan = " 3 " >
< asp:LinkButton ID = " lbtn_reguser " runat = " server " onclick = " lbtn_reguser_Click " > 注 册 </ asp:LinkButton >
< asp:LinkButton ID = " ltbn_forgetpass " runat = " server " > 忘记密码 ?</ asp:LinkButton >
</ td >
</ tr >
</ table >

</ div >
</ div >
</ form >
</ body >
</ html >

 

//default.aspx.cs代码

代码
 
   
using System;
using System.Configuration;
using System.Data;
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;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Init( object sender, EventArgs e)
{
this .validator_range_birth.MaximumValue = DateTime.Now.ToShortDateString();
this .validator_range_birth.MinimumValue = DateTime.Now.AddYears( - 150 ).ToShortDateString();
}

protected void Page_Load( object sender, EventArgs e)
{
if ( this .IsPostBack)
{
// this.Validate(); // 手动调用验证方法
}

}
protected void lbtn_reguser_Click( object sender, EventArgs e)
{
if ( this .IsValid) // 当所有页面对象验证通过后, 将设置Page的IsValid属性, 验证通过
{
DAL.CalendarUser calendaruser
= new DAL.CalendarUser();

// 初始birthday为空, 当串不为空时转换
DateTime ? birthday = null ;
if ( ! string .IsNullOrEmpty( this .txt_birth.Text))
{
birthday
= DateTime.Parse( this .txt_birth.Text);
}

// int a = calendaruser.CreateUser(this.txt_username.Text, this.txt_password.Text, this.txt_email.Text, birthday);
int exist = calendaruser.CreateUserByProc( this .txt_username.Text, this .txt_password.Text, this .txt_email.Text, birthday);

if (exist != 0 )
{
this .validator_custom_username.IsValid = false ; // 这里使用验证控件上的IsValid属性
}
}
}
protected void Validator_Dcode_ServerValidate( object source, ServerValidateEventArgs args)
{
// 每次复位Validator状态
args.IsValid = false ;

#region Cookie
// HttpCookie hc = this.Request.Cookies["Dcode"];
// if (hc != null)
// {
// string rqtcode = hc.Value.ToString();
// // if(rqtcode == args.Value)
// if (rqtcode == this.txt_dcode.Text)
// {
// args.IsValid = true; // 这里必须用args.IsValid, 不能用this.validator_dcode.isvalid = true, 因为最后args.IsValid会覆盖掉this.validator_dcode.IsValid, 分析在最后
// }
// }
// else
// {
// args.IsValid = false;
// }
#endregion

#region Session
if ( this .Session[ " Dycode " ] != null )
{
string num = this .Session[ " Dycode " ] as string ;
if (num == this .txt_dcode.Text)
{
args.IsValid
= true ;
}
else
{
args.IsValid
= false ;
}
}

#endregion
}
}

 

 

//DynamicCode.ashx代码

代码
 
   
<% @ WebHandler Language = " C# " Class = " DynamicCode " %>

using System;
using System.Web;

// 使用Session记得在ashx中, 添加IRequiresSessionState的接口, 而aspx文件默认就是支持的
public class DynamicCode : IHttpHandler,System.Web.SessionState.IRequiresSessionState {

public void ProcessRequest (HttpContext context) {
// context.Response.ContentType = "text/plain";
// context.Response.Write("Hello World");
context.Response.ContentType = " image/jpeg " ;

context.Response.Cache.SetCacheability(HttpCacheability.NoCache);

// 随机数生成器
Random ran = new Random();
int rannum = ran.Next( 10000 , 100000 );

// 创建位图文件
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap( 300 , 80 );

// 在位图文件上画画, 需要创建与图片画板相关的画图器
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap))
{
// 用Graphic对象清空背景
g.Clear(System.Drawing.Color.DarkGreen);

// 花矩形框
g.DrawRectangle( new System.Drawing.Pen(System.Drawing.Brushes.Blue, 3 ), 0 , 0 ,bitmap.Width - 1 ,bitmap.Height - 1 );

// StringFormat对象, 用来保存数字位置, 在数字矩形的绘图区域中
System.Drawing.StringFormat sf = new System.Drawing.StringFormat();
sf.Alignment
= System.Drawing.StringAlignment.Center;
sf.LineAlignment
= System.Drawing.StringAlignment.Center;

// 画数字, RectangleF用来确定显示数字的矩形区域
g.DrawString(rannum.ToString(),
new System.Drawing.Font( " 黑体 " , 50 ),
System.Drawing.Brushes.Black,
new System.Drawing.RectangleF( 0 , 0 , bitmap.Width, bitmap.Height),
sf);

// 画横线
for ( int i = 0 ; i < 80 ; i ++ )
{
g.DrawLine(
new System.Drawing.Pen(System.Drawing.Brushes.Black),
ran.Next(
0 , bitmap.Width),
ran.Next(
0 , bitmap.Height),
ran.Next(
0 , bitmap.Width),
ran.Next(
0 , bitmap.Height));
}

// 将数字保存到Cookie中
// HttpCookie hc = new HttpCookie("Dcode");
// hc.Value = rannum.ToString();
// context.Response.Cookies.Add(hc); // 保存到cookie中去, 但是没有页面对象, 所以需要通过context

// 将数字保存到Session中
context.Session[ " DyCode " ] = rannum.ToString();
}

// 保存图片到response, 注意: 这里是一般处理程序, 没有页面对象, 所以只能用context
bitmap.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
}

public bool IsReusable {
get {
return false ;
}
}

}

 

 

对args.IsValid和this.validator_dcode.IsValid的分析:
args是ServerVlidate事件处理方法的参数, 而this.validator_dcode.IsValid是验证控件上的IsValid属性.
这里又涉及到事件, 上边说过验证事件的处理是在Page_Load事件 --- Page_LoadComplete事件之间, 并且在控件事件之前. 顺便复习下事件, 事件仅仅是个有特殊的委托变量, 该委托变量指向堆中的一个委托对象 ---> 委托对象用来封装方法或函数, 以使我们可以达到传递方法的目的 ---> 但是封装完的方法仅仅是个地址(函数指针), C#不允许直接操作指针 ---> 所以提供了通过"变量名(参数列表)"的方式来调用方法 ---> 也就是"事件(参数列表)" ---> 而调一个空的方法又没有意义, 所以在类中又定义了一个事件触发方法, 判断事件上有方法时(非空)才触发事件. 触发方法格式如下:
protected void On事件名(EventArgs e)
{
    if(事件名 != null)
    {
        事件名(this,e);   //调用委托绑定的方法
    }
}
于是我们知道可以通过"事件(参数列表)"来调用, 而绑定的方法就是我们页面CS文件中的SerVerValidate(object source, ServerValidateEventArgs args). 当控件上触发这个事件时, 与该控件相关的信息都封装在了ServerValidateEventArgs类型的对象args中, 所以我们的事件处理方法中使用的属性都是从args对象里边来的, 当处理方法完成后, 将会根据args对象的结果信息修改控件上的属性, 包括this.validator_dcode.IsValid属性, ErrorMessage的赋值等工作, 因此最终会改掉this.validator_dcode.IsValid属性的值.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值