Asp.Mvc 2.0用户登录实例讲解---(4)服务器端验证

来源:岁月联盟 编辑:exp 时间:2012-05-22

这一节给大家讲解下ASP.NET MVC 2.0的服务器端验证的用法。大家知道,一个项目只用JS客户端验证是不安全的,用户可以禁用JS来绕过客户端验证,所以必须有服务器端验证。

关于服务器端验证,主要调用System.ComponentModel.DataAnnotations命名空间里面的类库。

具体用法参照:

http://msdn.microsoft.com/zh-cn/library/system.componentmodel.dataannotations.aspx

 

咱们这次还是以注册页面为例来讲解服务器端验证。

主要对注册页面做如下验证

1.用户名不能为空

 

2.密码不能为空,密码长度不能小于5位数,

 

3.密码和确认密码输入必须一样

 

4.邮件格式必须正确

 

咱们先看下效果图

 /


 

MVC中对所有字段的验证,实际上只需要在MODEL层设置验证规则就可以。

 

1.用户名验证

对用户名的验证,只需要验证用户名不为空就可以了,使用Required属性,把此属性绑定到MODEL的用户名字段上就可以了。

[csharp]  /// <summary>  
       /// 用户名  
       /// </summary>  
        [DisplayName("用户名")] 
        [Required(ErrorMessage="用户名不能为空!")] 
        public string UserName 
        { get; set; } 
/// <summary>
       /// 用户名
       /// </summary>
        [DisplayName("用户名")]
        [Required(ErrorMessage="用户名不能为空!")]
        public string UserName
        { get; set; }

 

  Required里面的参数表示具体的提示信息,此时如果用户名为空,就会在前台ASPX页面出现用户名不能为空的提示。当然要在前台显示错误的提示信息。使用<%:Html.ValidationMessageFor(m=>m.UserName)%>

标记就可以在前台显示错误的提示信息

 

2.密码验证

 

密码验证包括密码不能为空和密码长度限制。

验证密码为空和验证用户名为空一样,使用Required属性。

验证密码的长度使用StringLength属性

 

[csharp] /// <summary>  
       /// 密码  
       /// </summary>  
      [DisplayName("密码")] 
       [Required(ErrorMessage="密码不能为空")] 
       [StringLength(10, ErrorMessage = "密码长度不能小于5位",MinimumLength=5)] 
       public string UserPwd 
       { 
           get; 
           set; 
       } 
 /// <summary>
        /// 密码
        /// </summary>
       [DisplayName("密码")]
        [Required(ErrorMessage="密码不能为空")]
        [StringLength(10, ErrorMessage = "密码长度不能小于5位",MinimumLength=5)]
        public string UserPwd
        {
            get;
            set;
        }

 

StringLength的第一个参数表示密码的最大长度,ErrorMessage表示不满足条件的时候的错误提示信息。

MinimumLength表示输入内容的最小长度.

当然,前台必须有地方显示错误信息,显示错误信息我们使用如下

<%:Html.ValidationMessageFor(m=>m.UserPwd)%>

 

3.验证密码和确认密码是否一致

 

要验证密码和确认密码是否一致,这个稍微有点复杂,需要我们自定义验证规则。自定义验证规则我们需要继承ValidationAttribute类.然后实现它的isvaild方法.

 

[csharp] /// <summary>  
   /// 此自定义类用于验证密码和确认密码必须一致  
   /// </summary>  
   [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] 
   public class PwdMatch :ValidationAttribute 
   { 
 
       private object _typeid = new object(); 
       public string PWD { get; set; }//密码  
       public string ConfirmPwd { get; set; }//确认密码  
 
 
       public PwdMatch(string pwd, string confirmPwd) 
           : base() 
       { 
           PWD = pwd; 
           ConfirmPwd = confirmPwd; 
       } 
 
       /// <summary>  
       /// 返回错误的提示信息  
       /// </summary>  
       /// <param name="name"></param>  
       /// <returns></returns>  
       public override string FormatErrorMessage(string name) 
       { 
           return ErrorMessage; 
       } 
 
       /// <summary>  
       /// 重写TYPEID  
       /// </summary>  
       public override object TypeId 
       { 
           get 
           { 
               return _typeid; 
           } 
       } 
 
      /// <summary>  
      /// 判断是否想到  
      /// </summary>  
       /// <param name="value">value的值实际上是MODEL提交的MODEL类</param>  
      /// <returns></returns>  
       public override bool IsValid(object value) 
       { 
           PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value); 
           object originalValue = properties.Find(PWD, true ).GetValue(value);//获取密码  
           object confirmValue = properties.Find(ConfirmPwd, true).GetValue(value);//获取确认密码的值  
           return Object.Equals(originalValue, confirmValue); 
 
       } 
   } 
 /// <summary>
    /// 此自定义类用于验证密码和确认密码必须一致
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
    public class PwdMatch :ValidationAttribute
    {

        private object _typeid = new object();
        public string PWD { get; set; }//密码
        public string ConfirmPwd { get; set; }//确认密码


        public PwdMatch(string pwd, string confirmPwd)
            : base()
        {
            PWD = pwd;
            ConfirmPwd = confirmPwd;
        }

        /// <summary>
        /// 返回错误的提示信息
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public override string FormatErrorMessage(string name)
        {
            return ErrorMessage;
        }

        /// <summary>
        /// 重写TYPEID
        /// </summary>
        public override object TypeId
        {
            get
            {
                return _typeid;
            }
        }

       /// <summary>
       /// 判断是否想到
       /// </summary>
        /// <param name="value">value的值实际上是MODEL提交的MODEL类</param>
       /// <returns></returns>
        public override bool IsValid(object value)
        {
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
            object originalValue = properties.Find(PWD, true ).GetValue(value);//获取密码
            object confirmValue = properties.Find(ConfirmPwd, true).GetValue(value);//获取确认密码的值
            return Object.Equals(originalValue, confirmValue);

        }
    }
 

 

  PwdMatch属性类创建后,可把它标记在注册MODEL的上面,然后提交注册的时候,就会验证了

  [PwdMatch("UserPwd","ConfirPwd", ErrorMessage ="密¨¹码?与®?确¨¡¤认¨?不?匹£¤配?")]

    public class RegisterModel

{

 

}

 

  PwdMatch的第一个参数表上密码,名称与RegisterModel中的密码属性相同,

第二个字段是确认密码,名称与RegisterModel与的确认密码属性相同。

最后一个参数是错误提示信息.

 

当然,也要在前台显示错误提示信息,使用

<%:Html.ValidationSummary(true,"用®?户¡ì创ä¡ä建¡§失º¡ì败㨹!")%>就可以在前台显示一个总的错误信息列表.

 

4.邮箱验证

 

 邮箱验证主要是邮箱格式验证,验证格式是否满足要求.

验证邮箱我们使用RegularExpressions属性就可以

 

[csharp] /// <summary>  
       /// 用户邮箱  
       /// </summary>  
       [DisplayName("邮箱")] 
       //[DataType(DataType.EmailAddress)]  
       [RegularExpression(@"^/w+((-/w+)|(/./w+))*/@[A-Za-z0-9]+((/.|-)[A-Za-z0-9]+)*/.[A-Za-z0-9]+$", ErrorMessage = "电子邮件格式错误")] 
       public string Email 
       { 
           get; 
           set; 
       } 
 /// <summary>
        /// 用户邮箱
        /// </summary>
        [DisplayName("邮箱")]
        //[DataType(DataType.EmailAddress)]
        [RegularExpression(@"^/w+((-/w+)|(/./w+))*/@[A-Za-z0-9]+((/.|-)[A-Za-z0-9]+)*/.[A-Za-z0-9]+$", ErrorMessage = "电子邮件格式错误")]
        public string Email
        {
            get;
            set;
        }
 

 

第一个参数邮箱验证的正则表达式,第二个参数是错误提示信息.

 

在ASPX页面显示错误信息用

<%:Html.ValidationMessageFor(m=>m.Email)%>

 

 

 

以上是对用户注册信息的验证,当然,我们在提交信息的时候,要判断验证是否通过,我们使用ModelState.IsValid来判断验证是否通过,TRUE表示通过。FALSE表示未通过.

 

model代码

  

[csharp] /// <summary>  
    /// 注册用户MODEL  
    /// </summary>  
    [PwdMatch("UserPwd", "ConfirPwd", ErrorMessage = "密码与确认不匹配")] 
    public class RegisterModel 
    { 
       /// <summary>  
       /// 用户名  
       /// </summary>  
        [DisplayName("用户名")] 
        [Required(ErrorMessage="用户名不能为空!")] 
        public string UserName 
        { get; set; } 
 
        /// <summary>  
        /// 密码  
        /// </summary>  
       [DisplayName("密码")] 
        [Required(ErrorMessage="密码不能为空")] 
        [StringLength(10, ErrorMessage = "密码长度不能小于5位",MinimumLength=5)] 
        public string UserPwd 
        { 
            get; 
            set; 
        } 
 
       [DisplayName("确认密码")] 
       [Required(ErrorMessage="确认密码不能为空!")] 
       [StringLength(10, ErrorMessage = "确认密码长度不能小于5位",MinimumLength=5)] 
      public string ConfirPwd 
      { 
          get; 
          set; 
      } 
        /// <summary>  
        /// 用户邮箱  
        /// </summary>  
        [DisplayName("邮箱")] 
        //[DataType(DataType.EmailAddress)]  
        [RegularExpression(@"^/w+((-/w+)|(/./w+))*/@[A-Za-z0-9]+((/.|-)[A-Za-z0-9]+)*/.[A-Za-z0-9]+$", ErrorMessage = "电子邮件格式错误")] 
        public string Email 
        { 
            get; 
            set; 
        } 
 
     
    } 
 
    
    /// <summary>  
    /// 此自定义类用于验证密码和确认密码必须一致  
    /// </summary>  
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] 
    public class PwdMatch :ValidationAttribute 
    { 
 
        private object _typeid = new object(); 
        public string PWD { get; set; }//密码  
        public string ConfirmPwd { get; set; }//确认密码  
 
 
        public PwdMatch(string pwd, string confirmPwd) 
            : base() 
        { 
            PWD = pwd; 
            ConfirmPwd = confirmPwd; 
        } 
 
        /// <summary>  
        /// 返回错误的提示信息  
        /// </summary>  
        /// <param name="name"></param>  
        /// <returns></returns>  
        public override string FormatErrorMessage(string name) 
        { 
            return ErrorMessage; 
        } 
 
        /// <summary>  
        /// 重写TYPEID  
        /// </summary>  
        public override object TypeId 
        { 
            get 
            { 
                return _typeid; 
            } 
        } 
 
       /// <summary>  
       /// 判断是否想到  
       /// </summary>  
        /// <param name="value">value的值实际上是MODEL提交的MODEL类</param>  
       /// <returns></returns>  
        public override bool IsValid(object value) 
        { 
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value); 
            object originalValue = properties.Find(PWD, true ).GetValue(value);//获取密码  
            object confirmValue = properties.Find(ConfirmPwd, true).GetValue(value);//获取确认密码的值  
            return Object.Equals(originalValue, confirmValue); 
 
        } 
    } 
/// <summary>
    /// 注册用户MODEL
    /// </summary>
    [PwdMatch("UserPwd", "ConfirPwd", ErrorMessage = "密码与确认不匹配")]
    public class RegisterModel
    {
       /// <summary>
       /// 用户名
       /// </summary>
        [DisplayName("用户名")]
        [Required(ErrorMessage="用户名不能为空!")]
        public string UserName
        { get; set; }

        /// <summary>
        /// 密码
        /// </summary>
       [DisplayName("密码")]
        [Required(ErrorMessage="密码不能为空")]
        [StringLength(10, ErrorMessage = "密码长度不能小于5位",MinimumLength=5)]
        public string UserPwd
        {
            get;
            set;
        }

       [DisplayName("确认密码")]
       [Required(ErrorMessage="确认密码不能为空!")]
       [StringLength(10, ErrorMessage = "确认密码长度不能小于5位",MinimumLength=5)]
      public string ConfirPwd
      {
          get;
          set;
      }
        /// <summary>
        /// 用户邮箱
        /// </summary>
        [DisplayName("邮箱")]
        //[DataType(DataType.EmailAddress)]
        [RegularExpression(@"^/w+((-/w+)|(/./w+))*/@[A-Za-z0-9]+((/.|-)[A-Za-z0-9]+)*/.[A-Za-z0-9]+$", ErrorMessage = "电子邮件格式错误")]
        public string Email
        {
            get;
            set;
        }

   
    }

  
    /// <summary>
    /// 此自定义类用于验证密码和确认密码必须一致
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
    public class PwdMatch :ValidationAttribute
    {

        private object _typeid = new object();
        public string PWD { get; set; }//密码
        public string ConfirmPwd { get; set; }//确认密码


        public PwdMatch(string pwd, string confirmPwd)
            : base()
        {
            PWD = pwd;
            ConfirmPwd = confirmPwd;
        }

        /// <summary>
        /// 返回错误的提示信息
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public override string FormatErrorMessage(string name)
        {
            return ErrorMessage;
        }

        /// <summary>
        /// 重写TYPEID
        /// </summary>
        public override object TypeId
        {
            get
            {
                return _typeid;
            }
        }

       /// <summary>
       /// 判断是否想到
       /// </summary>
        /// <param name="value">value的值实际上是MODEL提交的MODEL类</param>
       /// <returns></returns>
        public override bool IsValid(object value)
        {
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
            object originalValue = properties.Find(PWD, true ).GetValue(value);//获取密码
            object confirmValue = properties.Find(ConfirmPwd, true).GetValue(value);//获取确认密码的值
            return Object.Equals(originalValue, confirmValue);

        }
    }
 

 

 

前台页面代码

[html] <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<MvcLogin.Models.RegisterModel>" %> 
 
<!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>注册页面</title> 
    <script type="text/javascript" src="../../Scripts/jquery-1.4.1-vsdoc.js"></script> 
    <script type="text/javascript" src="../../Scripts/jquery.validate.js"></script> 
    <script type="text/javascript"> 
//        $().ready(function () { 
//            $("#form1").validate( 
//        { 
//            rules: 
//           { 
//               UserName: 
//              { 
//                  required: true 
//              }, 
//               UserPwd: 
//               { 
//                   required: true, 
//                   minlength: 6 
//               }, 
//               ConfirPwd: 
//               { 
//                   required: true, 
//                   minlength: 6, 
//                   equalTo: "#UserPwd" 
 
//               }, 
//               Email: 
//               { 
//                   email: true 
//               } 
 
//           }, 
//            messages: 
//           { 
//               UserName: 
//              { 
//                  required: "<span style='color:red'>用户名不能为空! </span>" 
//              }, 
 
//               UserPwd: 
//              { 
//                  required: "<span style='color:red'>密码不能为空!</span>", 
//                  minlength: jQuery.format("<span style='color:red'>密码长度不能小于{0}个字符!</span>") 
//              }, 
//               ConfirPwd: 
//               { 
//                   required: "<span style='color:red'>确认密码不能为空!<span>", 
//                   minlength: jQuery.format("确认密码长度不能小于{0}个字符!"), 
//                   equalTo: "<span style='color:red'>两次输入密码不一致!</span>" 
 
//               }, 
//               Email: 
//               { 
//                   email: "<span style='color:red'>邮箱输入格式不正确!</span>" 
//               } 
//           }, 
//            onkeyup: false 
//        }); 
 
//        }); 
    </script> 
</head> 
<body> 
    <div> 
    <br /> 
 
    <p style="font-size:12px;color:red"> 
 
    <%if (ViewData["msg"] != null) 
      {%> 
    <%:ViewData["msg"]%> 
    <%} %> 
    </p> 
    <br /> 
    <p> 
      <%:Html.ValidationSummary(true,"用户创建失败!") %> 
    </p> 
    <%Html.BeginForm("Register", "user", FormMethod.Post, new  { name="form1",id="form1"}) ; %> 
 
  
        <table> 
           <tr> 
             <td><%: Html.LabelFor(m => m.UserName) %></td> 
             <td>  <%: Html.TextBoxFor(m => m.UserName) %></td> 
             <td><%:Html.ValidationMessageFor(m=>m.UserName) %></td> 
           </tr> 
 
              <tr> 
             <td> <%: Html.LabelFor(m => m.UserPwd) %></td> 
             <td>   <%: Html.PasswordFor(m => m.UserPwd) %></td> 
              <td><%:Html.ValidationMessageFor(m=>m.UserPwd) %></td> 
           </tr> 
 
              <tr> 
             <td> <%: Html.LabelFor(m => m.ConfirPwd) %></td> 
             <td> <%: Html.PasswordFor(m => m.ConfirPwd)%></td> 
              <td><%:Html.ValidationMessageFor(m=>m.ConfirPwd) %></td> 
           </tr> 
 
              <tr> 
             <td>    <%: Html.LabelFor(m => m.Email) %></td> 
             <td>  <%: Html.TextBoxFor(m => m.Email) %></td> 
              <td><%:Html.ValidationMessageFor(m=>m.Email) %></td> 
           </tr> 
 
              <tr> 
             <td> <input type="submit" value="提交" /></td> 
             <td></td> 
              <td></td> 
           </tr> 
 
 
        </table> 
 
 
 
    <%Html.EndForm(); %> 
     
    </div> 
</body> 
</html> 
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<MvcLogin.Models.RegisterModel>" %>

<!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>注册页面</title>
    <script type="text/javascript" src="../../Scripts/jquery-1.4.1-vsdoc.js"></script>
    <script type="text/javascript" src="../../Scripts/jquery.validate.js"></script>
    <script type="text/javascript">
//        $().ready(function () {
//            $("#form1").validate(
//        {
//            rules:
//           {
//               UserName:
//              {
//                  required: true
//              },
//               UserPwd:
//               {
//                   required: true,
//                   minlength: 6
//               },
//               ConfirPwd:
//               {
//                   required: true,
//                   minlength: 6,
//                   equalTo: "#UserPwd"

//               },
//               Email:
//               {
//                   email: true
//               }

//           },
//            messages:
//           {
//               UserName:
//              {
//                  required: "<span style='color:red'>用户名不能为空! </span>"
//              },

//               UserPwd:
//              {
//                  required: "<span style='color:red'>密码不能为空!</span>",
//                  minlength: jQuery.format("<span style='color:red'>密码长度不能小于{0}个字符!</span>")
//              },
//               ConfirPwd:
//               {
//                   required: "<span style='color:red'>确认密码不能为空!<span>",
//                   minlength: jQuery.format("确认密码长度不能小于{0}个字符!"),
//                   equalTo: "<span style='color:red'>两次输入密码不一致!</span>"

//               },
//               Email:
//               {
//                   email: "<span style='color:red'>邮箱输入格式不正确!</span>"
//               }
//           },
//            onkeyup: false
//        });

//        });
    </script>
</head>
<body>
    <div>
    <br />

    <p style="font-size:12px;color:red">

    <%if (ViewData["msg"] != null)
      {%>
    <%:ViewData["msg"]%>
    <%} %>
    </p>
    <br />
    <p>
      <%:Html.ValidationSummary(true,"用户创建失败!") %>
    </p>
    <%Html.BeginForm("Register", "user", FormMethod.Post, new  { name="form1",id="form1"}) ; %>

 
        <table>
           <tr>
             <td><%: Html.LabelFor(m => m.UserName) %></td>
             <td>  <%: Html.TextBoxFor(m => m.UserName) %></td>
             <td><%:Html.ValidationMessageFor(m=>m.UserName) %></td>
           </tr>

              <tr>
             <td> <%: Html.LabelFor(m => m.UserPwd) %></td>
             <td>   <%: Html.PasswordFor(m => m.UserPwd) %></td>
              <td><%:Html.ValidationMessageFor(m=>m.UserPwd) %></td>
           </tr>

              <tr>
             <td> <%: Html.LabelFor(m => m.ConfirPwd) %></td>
             <td> <%: Html.PasswordFor(m => m.ConfirPwd)%></td>
              <td><%:Html.ValidationMessageFor(m=>m.ConfirPwd) %></td>
           </tr>

              <tr>
             <td>    <%: Html.LabelFor(m => m.Email) %></td>
             <td>  <%: Html.TextBoxFor(m => m.Email) %></td>
              <td><%:Html.ValidationMessageFor(m=>m.Email) %></td>
           </tr>

              <tr>
             <td> <input type="submit" value="提交" /></td>
             <td></td>
              <td></td>
           </tr>


        </table>

 

    <%Html.EndForm(); %>
   
    </div>
</body>
</html>
 

 

  controller代码

  

[csharp] /// <summary>  
    /// 注册提交  
    /// </summary>  
    /// <param name="model"></param>  
    /// <returns></returns>  
    [HttpPost] 
    public ActionResult Register(Models.RegisterModel model) 
    { 
        if (ModelState.IsValid) 
        { 
            //验证通过  
            bool result = false; 
            if (!new Models.SqlHelper().ExistUser(model)) 
            { 
                result = new Models.SqlHelper().AddUser(model); 
            } 
 
            if (result) 
            { 
                //添加成功转向主页  
                FormsService.SignIn(model.UserName, false); 
                return RedirectToAction("index"); 
            } 
            else 
            { 
                //返回注册页面  
                ViewData["msg"] = "添加用户失败"; 
                return View(model); 
            } 
 
        } 
        else 
        { 
            //验证不通过  
            //返回注册页面  
            ViewData["msg"] = "添加用户失败"; 
            return View(model); 
        } 
    } 
    /// <summary>
        /// 注册提交
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Register(Models.RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                //验证通过
                bool result = false;
                if (!new Models.SqlHelper().ExistUser(model))
                {
                    result = new Models.SqlHelper().AddUser(model);
                }

                if (result)
                {
                    //添加成功转向主页
                    FormsService.SignIn(model.UserName, false);
                    return RedirectToAction("index");
                }
                else
                {
                    //返回注册页面
                    ViewData["msg"] = "添加用户失败";
                    return View(model);
                }

            }
            else
            {
                //验证不通过
                //返回注册页面
                ViewData["msg"] = "添加用户失败";
                return View(model);
            }
        }

 

demo下载:http://www.2cto.com/uploadfile/2012/0522/20120522103005738.rar
 

 

 

摘自 奶酪专栏