zoukankan      html  css  js  c++  java
  • 【ASP.NET MVC 学习笔记】- 17 Model验证

    本文参考:http://www.cnblogs.com/willick/p/3434483.html

    1、Model验证用于在实际项目中对用户提交的表单的信息进行验证,MVC对其提供了很好的支持。

    2、ModelState 是 Controller 抽象类的一个属性,它是 MVC 处理完验证时要使用的一核心对象,提供了对验证结果的存、取和判断。所以验证用户提交的数据,最直接的方法是在Action方法中使用 ModelState 对Model对象的属性值自行判断合法性。示例:

    [HttpPost] 
    public ViewResult MakeBooking(Appointment appt) 
    { 
        if (string.IsNullOrEmpty(appt.ClientName)) 
        { 
            ModelState.AddModelError("ClientName", "Please enter your name"); //ModelState.AddModelError用于添加错误信息
        } 
        if (ModelState.IsValidField("Date") && DateTime.Now > appt.Date) //ModelState.IsValidField 方法用于检查用户提交的值是否能够被Model Binder成功赋值给指定的属性
        { 
            ModelState.AddModelError("Date", "Please enter a date in the future"); 
        } 
        if (!appt.TermsAccepted) 
        { 
            ModelState.AddModelError("TermsAccepted", "You must accept the terms"); 
        } 
        if (ModelState.IsValid) 
        { 
            return View("Completed", appt); 
        } else 
        { 
            return View(); 
        } 
    }

    3、验证消息的显示,可以简单的分为两种,一种是Model级的,另一种是属性级的。Model级示例:

    @using (Html.BeginForm()) { 
        @Html.ValidationSummary()
        <p>Your name: @Html.EditorFor(m => m.ClientName)</p> 
        ...
    }
    //Html.ValidationSummary()还有三些重载方法:Html.ValidationSummary(bool)  、 Html.ValidationSummary(string)  和 Html.ValidationSummary(bool, string) 。
    //第一个是当参数为true时,只显示Model级的验证消息(如果 ModelState.AddModelError 方法的第一个参数没有指定属性名称,则为Model级的);第二个是为所有的验证消息显示一个标题;第三个是前两个的结合。

        属性级示例:

    @using (Html.BeginForm()) 
    {
        @Html.ValidationSummary(true)
        <p>@Html.ValidationMessageFor(m => m.ClientName)</p>
        <p>Your name: @Html.EditorFor(m => m.ClientName)</p>
        <p>@Html.ValidationMessageFor(m => m.Date)</p>
        <p>Appointment Date: @Html.EditorFor(m => m.Date)</p>
        <p>@Html.ValidationMessageFor(m => m.TermsAccepted)</p>
        <p>@Html.EditorFor(m => m.TermsAccepted) I accept the terms & conditions</p>
        <input type="submit" value="Make Booking" />
    }

    4、处理在Action方法中进行验证,默认的ModelBinder在对值进行绑定时也有验证处理。示例:

    [HttpPost]
    public ViewResult MakeBooking(Appointment appt) 
    {
        if (ModelState.IsValid) 
        {
            return View("Completed", appt);
        } else 
        {
            return View();
        } 
    }

    5、对于MVC模式来说,如果把验证的规则放在自定义的 Model Binder 类中似乎并不合适。更多的时候我们会选择使用元数据的方式把验证的规则放在Model类中。示例:

    public class Appointment 
    { 
        [Required] 
        public string ClientName { get; set; } 
    
        [DataType(DataType.Date)] 
        [Required(ErrorMessage="Please enter a date")]
      public DateTime Date { get; set; } 
    
        [Range(typeof(bool), "true", "true", ErrorMessage = "You must accept the terms")]
      public bool TermsAccepted { get; set; } 
    }

       MVC内置的验证特性如下图:

      

    6、我们也可以通过继承ValidationAttribute类自定义验证特性。示例:

    public class MustBeTrueAttribute : ValidationAttribute
    { 
        public override bool IsValid(object value) 
        { 
            return value is bool && (bool)value; 
        } 
    }

    7、我们也可以继承内置的特性自定义验证特性。示例

    public class FutureDateAttribute : RequiredAttribute 
    { 
        public override bool IsValid(object value) 
        { 
            return base.IsValid(value) && ((DateTime)value) > DateTime.Now; 
        } 
    }

    8、Model级别的自定义验证。示例:

    //Joe这个人星期一这天不能预约
    public class NoJoeOnMondaysAttribute : ValidationAttribute 
    { 
        public NoJoeOnMondaysAttribute() 
        { 
            ErrorMessage = "Joe cannot book appointments on Mondays"; 
        } 
    
        public override bool IsValid(object value) 
        { 
            Appointment app = value as Appointment; 
            if (app == null || string.IsNullOrEmpty(app.ClientName) || app.Date == null) 
    {
    return true; }
    else
         {
    return !(app.ClientName == "Joe" && app.Date.DayOfWeek == DayOfWeek.Monday); } } }
    [NoJoeOnMondays] 
    public class Appointment 
    { 
        ...
    }

    9、Model 的自验证,即在 Model 类内部编写验证逻辑方法,通过实现 IValidatableObject 接口来告诉 MVC 该某个 Model 是否为自验证的 Model。示例:

    public class Appointment : IValidatableObject 
    {
    public string ClientName { get; set; } [DataType(DataType.Date)] public DateTime Date { get; set; } public bool TermsAccepted { get; set; } public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    { List
    <ValidationResult> errors = new List<ValidationResult>(); if (string.IsNullOrEmpty(ClientName)) { errors.Add(new ValidationResult("Please enter your name")); } if (DateTime.Now > Date) { errors.Add(new ValidationResult("Please enter a date in the future")); } if (errors.Count == 0 && ClientName == "Joe" && Date.DayOfWeek == DayOfWeek.Monday) { errors.Add(new ValidationResult("Joe cannot book appointments on Mondays")); } if (!TermsAccepted) { errors.Add(new ValidationResult("You must accept the terms")); } return errors; } }

        如果一个 Model 实现了 IValidatableObject 接口,MVC 会在 Model Binder 为 Model 的每个属性赋值后调用Validate方法。相对于在 Action 方法中的验证,这种 Model 自验证更为灵活,而且把验证逻辑放在对应的Model中,保证了代码的一致性,方便维护。

    10、客户端验证在Web.config中有两个开关,默认都是启用的,如下:

    <appSettings> 
        <add key="ClientValidationEnabled" value="true"/> 
        <add key="UnobtrusiveJavaScriptEnabled" value="true"/> 
    </appSettings> 

        要启用客户端验证,这两个值都需要设为true。你也可以在单个的View中通过设置HtmlHelper.ClientValidationEnabled 和 HtmlHelper.UnobtrusiveJavaScriptEnabled的值来开启或关闭客户端验证。启用时还需要包含三个JS引用:

    • /Scripts/ jquery-1.7.1.min.js
    • /Scripts/ jquery.validate.min.js
    • /Scripts/ jquery.validate.unobtrusive.min.js

        当我们启用客户端验证后,要使用起来,最简单的方便是对Model应用验证特性,如Required、Range等。为了演示,我们修改 Appointment 类如下:

    public class Appointment 
    {
        [Required]
        [StringLength(10, MinimumLength = 3)]
        public string ClientName { get; set; }
    
        [DataType(DataType.Date)]
        public DateTime Date { get; set; }
    
        public bool TermsAccepted { get; set; }
    }
    

         这里的验证规则是通过后台指定的。但并不是所有后台使用的验证都有对应的客户端验证,例如 action 中的验证、应用Model级的验证特性和Model的自验证都是没有客户端验证的。

         Tips:使用 MVC 提供的客户端验证的好处:不用写 JavaScript 代码;用户可以即时的看到验证消息,更快地得到反馈,如果用户禁用了JavaScript, MVC 就会走后台验证。

    11、Remote 验证实际上就是通过 Ajax 实现的,只是被MVC封装好了,用起来简单多了,也不需要写 JavaScript 代码。示例:

    //1、定义验证方法
    public JsonResult ValidateDate(string Date) {
        DateTime parsedDate;
        if (!DateTime.TryParse(Date, out parsedDate)) {
            return Json("Please enter a valid date (yyyy/mm/dd)", JsonRequestBehavior.AllowGet);
        }
        else if (DateTime.Now > parsedDate) {
            return Json("Please enter a date in the future", JsonRequestBehavior.AllowGet);
        }
        else {
            return Json(true, JsonRequestBehavior.AllowGet);
        }
    }
    
    //2、使用
    public class Appointment 
    {
        public string ClientName { get; set; }
    
        [DataType(DataType.Date)]
        [Remote("ValidateDate", "Home")]
        public DateTime Date { get; set; }
    
        public bool TermsAccepted { get; set; }
    }

        效果上和客户端验证差不多,但验证的处理是在 Controller 中的 Action 中发生的。应用 Remote 特性的字段,每次改变它的值都会调用一次后台,所以从某种意义上来说,我们应该尽量避免使用这种验证,除了那种不得不与后台交互的验证,如检查一个用户名是否已经存在。

  • 相关阅读:
    阿里云:面向5G时代的物联网无线连接服务
    走近科学,探究阿里闲鱼团队通过数据提升Flutter体验的真相
    Redis 5.0新功能介绍
    阿里云发布 Redis 5.0 缓存服务:全新 Stream 数据类型带来不一样缓存体验
    荣获“5G MEC优秀商用案例奖”,阿里云边缘计算发力新零售
    阿里云亮相2019联通合作伙伴大会,边缘计算等3款云产品助力5G时代产业数字化转型
    noip2014 寻找道路
    noip2014 无线网络发射器选址
    noip2014 联合权值
    noip2013 华容道
  • 原文地址:https://www.cnblogs.com/wangwust/p/6392788.html
Copyright © 2011-2022 走看看