ASP.NET MVC5(四):数据注解和验证
2021-07-14 20:06
标签:引用 ice attr 框架 path ted ajax 准备 omv 用户输入验证的工作,不仅要在客户端浏览器中执行,还要在服务端执行。主要原因是客户端验证会对输入数据给出即时反馈,提高用户体验;服务器端验证,主要是因为不能完全信任用户提供的数据。ASP.NET MVC框架提供了强大的验证组件帮助我们处理这些繁杂的问题。 验证注解特性定义在命名空间System.ComponentModel.DataAnnotations中,它们提供了服务器端验证的功能,当在模型的属性上使用时,框架也支持客户端验证。常用特性简介: 下面,通过一个简单的示例来讲解这些特性的使用方法。 添加BooksController,启动项目,此时,ASP.NET MVC已经利用基架模板帮助我们创建好了相应的controller和View,直接将浏览器定位到/Books/Create,可浏览如下用来添加书籍的页面。 在添加书籍时,用户希望对输入的数据进行一些验证,当输入的数据无法通过相关验证时,返回错误信息。此时,验证注解特性就派上了用场。 向BooksController中添加CheckContent方法(为了使用remote特性做准备) 修改Book类,分别添加验证注解: 重新启动项目,在Create页面输入不符合验证逻辑的数据,效果如下: 重新输入正确的数据,点击Create,数据成功录入后,我们再录入另外一本书籍,Content内容与上一次添加的内容相同,得到错误信息,此时Remote特性调用了CheckContent方法进行验证。 每个验证特性都允许传入一个带有自定义错误提示消息的参数,例如以上示例中RegularExpression特性返回的错误消息,用户可能无法理解正则表达式的含义,此时,我们就需要返回一些简单易懂的错误消息,向RegularExpression传入ErrorMessage参数。 效果如下: 默认情况下,ASP.NET MVC框架在模型绑定时执行验证逻辑。模型绑定器一旦使用新值完成对模型属性的更新,就会利用当前的模型元数据获得模型的所有验证器。ASP.NET MVC运行时提供了一个验证器DataAnnotationsModelValidator来与数据注解一同工作。这个模型验证器会找到所有的验证特性并执行它们包含的验证逻辑。模型绑定器捕获所有失败的验证规则并把它们存放在模型状态中。 控制器操作决定了在模型验证失败或成功时程序的执行流程。通常情况下,验证成功,保存用户输入数据,验证失败,重新渲染视图,返回错误消息。以下是系统自动创建的Create方法,首先判断模型状态ModelState是否存在错误,若不存在,则保存书籍信息,若存在败,则重新渲染视图。 上一节中介绍了这么多验证注解,我们不禁会问,用户经常会提出很多奇葩的需求,我们能否自己定义一些验证逻辑呢?答案是肯定的。本节,将介绍如何完成自定义逻辑验证。 所有验证注解特性最终都派生自基类ValidationAttribute,它是个抽象类,因此,创建自定义注解特性时也必须派生自ValidationAttribute类。 首先,添加CheckAuthorAttribute类派生自基类ValidationAttribute: 为了实现这个验证,需要重写基类的IsValid方法,ValidationContext参数提供了可在IsValid方法内部使用的信息,如模型类型、模型对象实例、用来验证属性的显示名称等。IsValid方法的第一个参数是要验证的对象的值,另外,我们通过构造函数获取不能通过验证的人名。 上述代码有两点需要注意: 修改Book类,在Author属性上添加CheckAuthor特性。 运行程序,输入Author,点击Create,效果如下: 到目前为止,我们已经成功创建自定义注解特性,但是细心的用户又发现了,新添加的验证只有在点击了Create后才能触发,其他的验证都可以给出即时反馈。正如用户所说,目前我们只添加了服务端验证,下面将介绍如何为CheckAuthor特性添加客户端验证。 修改MaxWordsAttribute类,使其继承IClientValidatable接口,实现GetClientValidationRules方法。 说明: 在Scripts文件夹下添加JavaScript文件,命名为customvalidators.js,键入如下代码: 说明: 最后,在Views/Books/Create.cshtml中添加对customvalidators.js的引用: 启动程序,将Url定位到/Books/Create,在Author文本框中输入Thomas,当焦点离开Author文本框后即可完成验证。 ASP.NET MVC5(四):数据注解和验证 标签:引用 ice attr 框架 path ted ajax 准备 omv 原文地址:http://www.cnblogs.com/zhangyingai/p/7074498.html前言
数据验证
验证注解的使用
当属性值为null或者空时,将引发一个验证错误,可以理解为若添加了Required特性,则此项为必填项。
限定字符串长度。
使用正则表达式验证输入的字符串是否符合格式要求。
用来指定输入数值来的最小值和最大值。
用来判断两个属性是否拥有相同的值。例如,确保两次输入的密码相同。
利用服务器端的回调函数执行客户端的逻辑验证。
假设现在我们开发一套图书管理系统,在Models文件夹中创建Book类,用来保存书籍的基本信息。public class Book
{
public int Id { get; set; }
public string Name { get; set; }
public string Author { get; set; }
public int PagesNumber { get; set; }
public string Publisher { get; set; }
public string PublicationDate { get; set; }
public string Content { get; set; }
public decimal Price { get; set; }
public decimal PriceConfirm { get; set; }
}
第一步,引入命名空间using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
public JsonResult CheckContent(string content)
{
var result = db.Books.Where(m => m.Content == content).Count() == 0;
return Json(result, JsonRequestBehavior.AllowGet);
}
public int Id { get; set; }
[Required] //必填
public string Name { get; set; }
[StringLength(50)] //作者姓名的长度不能超过50个字符
public string Author { get; set; }
[Range(100, 10000)] //页数保证在100~10000页之间
public int PagesNumber { get; set; }
public string Publisher { get; set; }
[RegularExpression(@"^\d{4}(\-|\/|\.)\d{1,2}\1\d{1,2}$")] //日期格式
public string PublicationDate { get; set; }
[Remote("CheckContent", "Books")] //内容介绍不能重复
public string Content { get; set; }
public decimal Price { get; set; }
[System.ComponentModel.DataAnnotations.Compare("Price")] //两次输入的价格必须一致
public decimal PriceConfirm { get; set; }
★注意,Remote特性自动发送AJAX请求访问后台代码来实现验证,它只有客户端验证,没有服务端验证。也就是说,当用户浏览器关闭js,Remote检查将不起作用,因此,Remote特性存在一定的安全隐患。同理,如果创建Controller时没有勾选Reference script libraries选项,Remote特性也将不起任何作用。
自定义错误提示
[RegularExpression(@"^\d{4}(\-|\/|\.)\d{1,2}\1\d{1,2}$",ErrorMessage ="请输入有效的日期格式,例如:2017-06-16")] //日期格式
public string PublicationDate { get; set; }
验证注解的后台原理及控制器操作
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Name,Author,PagesNumber,Publisher,PublicationDate,Content,Price,PriceConfirm")] Book book)
{
if (ModelState.IsValid)
{
db.Books.Add(book);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(book);
}
自定义验证逻辑
自定义注解
假设用户提出一个需求,由于某位作者遭到无情封杀,录入书籍信息时,作者一栏不能为指定的人名。using System.ComponentModel.DataAnnotations;
namespace MyFirstMvcProject.Infrastructure
{
public class CheckAuthorAttribute : ValidationAttribute
{
}
}
public class CheckAuthorAttribute : ValidationAttribute
{
public string Author { get; set; }
public CheckAuthorAttribute(string author) : base("{0} can not be this one. ")
{
this.Author = author;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value != null)
{
if (value.ToString() == Author)
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
}
return ValidationResult.Success;
}
}
[StringLength(50)] //作者姓名的长度不能超过50个字符
[CheckAuthor("Thomas", ErrorMessage = "Author can not be this one.")]
public string Author { get; set; }
public class CheckAuthorAttribute : ValidationAttribute, IClientValidatable
{
public string Author { get; set; }
public CheckAuthorAttribute(string author) : base("{0} can not be this one. ")
{
this.Author = author;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value != null)
{
if (value.ToString() == Author)
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
}
return ValidationResult.Success;
}
public IEnumerable
///
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}