zoukankan      html  css  js  c++  java
  • 学习笔记验证控件

    作为程序员, 永远别指望用户按照规则进行输入, 比较理想的状况是在客户端浏览器和服务器端进行双重验证. 通常在客户端浏览器进行非功能性的常规验证, 如: 非空验证、范围验证及输入格式验证等, 而在服务器端进行功能性验证, 如: 检查账户是否存在, 检查用户权限等. 客户端浏览器的验证一般通过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
    {
    95%;
    height: 216px;
    }
    .style5
    {
    }
    .style6
    {
    57px;
    }
    </style>
    </head>
    <body>
    <form id="form1" runat="server">
    <div style="text-align:center;">
    <div style=" 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属性的值.

  • 相关阅读:
    HDOJ 2095 find your present (2)
    HDOJ 2186 悼念512汶川大地震遇难同胞——一定要记住我爱你
    九度 1337 寻找最长合法括号序列
    九度 1357 疯狂地Jobdu序列
    HDOJ 1280 前m大的数
    九度 1343 城际公路网
    九度 1347 孤岛连通工程
    HDOJ 2151 Worm
    九度 1342 寻找最长合法括号序列II
    九度 1346 会员积分排序
  • 原文地址:https://www.cnblogs.com/cs_net/p/1875320.html
Copyright © 2011-2022 走看看