DRY(“Don’t Repeat Yourself”)是MVC的设计原则之一。ASP.NET MVC鼓励你只定义一次功能或行为,然后在应用程序中各处进行使用。这会大大 减少需要编写的代码量,使你的代码不容易出错,更便于测试和维护。
MVC和Entity Framework Core Code First所提供的验证功能是实际应用中DRY原则的一个很好的实例。你可以在一个地方(在模型类中)声明指定的验证规则,在整个应用中生效。
DataAnnotations提供了一组内置的验证特性,你可以应用在任何类或者属性中。(字也包含了类似于 DataType
这样的格式化特性来帮助你格式化数据而不是提供任何验证功能)
添加内置的 Required
, StringLength
, RegularExpression
和 Range
验证特性。
public class User { public int ID { get; set; } [Display(Name = "姓名")] [StringLength(10, MinimumLength = 3)] [Required] public string Name { get; set; } [Display(Name = "邮箱")] [DataType(DataType.EmailAddress)] public string Email { get; set; } [Display(Name = "身高")] [Required] [Range(150, 230)] public decimal Height { get; set; } [Display(Name = "职称")] public string Title { get; set; } [Display(Name = "部门")] public string Dept { get; set; } [Display(Name = "简介")] public string Bio { get; set; } }
其中 Required
和 MinimumLength
Attribute表示属性不能为空;但无法阻止用户输入空格来满足该验证条件。 RegularExpression
Attribute用来限制用户可以输入的字符。 Range
Attribute限制值必须在指定的范围内。 StringLength
Attribute可让你设置字符串的最大长度,和可选的最小长度。值类型(例如 decimal
, int
, float
, DateTime
)是自身必须的,不需要 [Required]
Attribute。
在输入错误的数据时,jQuery客户端验证马上会发现错误,并显示一个错误信息。注意表单在每个包含无效数据的字段下自动呈现适当的验证错误消息。错误会在客户端(使用JavaScript和jQuery)和服务器端执行。
你会发现你不需要修改 UserController
类或者 Create.cshtml
视图中的一行代码,就可以验证UI。之前创建的Controller和视图会自动使用你在 User
模型类中属性上指定的验证特性规则。使用 Edit
操作方法测试验证,同样会生效。
你可能会好奇在没有对控制器或者视图进行更新的情况下验证UI是如何产生的。
// GET: User/Create public IActionResult Create() { return View(); } // POST: User/Create // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see http://go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create([Bind("ID,Name,Email,Bio,Height,Title,Dept")]User user) { if (ModelState.IsValid) { _context.Add(user); await _context.SaveChangesAsync(); return RedirectToAction("Index"); } return View(user); }
第一个(HTTP GET) Create
方法显示初始的Create表单。第二个( [HttpPost]
)版本负责处理POST请求,通过调用 ModelState.IsValid
来检查是否有任何验证错误。调用该方法会验证任何已应用到对对象上的验证。如果对象有验证错误, Create
方法会重新显示表单。如果没有错误,方法会保存数据到数据库。
在这个例子中,在客户端验证检测到错误时,表单不会POST到服务器,如果你在浏览器中禁用了JS,客户端验证将会禁用,那么HTTP POST Create
方法中的 ModelState.IsValid
会检测任何验证错误。
Input Tag Helper
会使用(Consume) DataAnnotations
特性并在客户端产生(Produce)jQuery验证所需要的HTML属性。 Validation Tag Helper
负责显示验证错误。
非常Nice的是这个方案控制器和视图模板不需要知道任何实际执行的验证规则或者具体的错误消息。验证规则和错误字符串只在模型类中指定。同样的骓规则会自动地应用到任何你想要创建或者修改该Model的视图模板。
当你想更改验证逻辑时,你只需要在一个地方给Model添加验证特性。不用担心应用的不同部分执行不同的验证规则 - 所有的验证逻辑在同一个地方定义,在各处使用。这意味着你充分遵循了DRY原则。
System.ComponentModel.DataAnnotations
命名空间提供了内置的验证特性以外的格式化特性。比如:
[Display(Name = "生日")] [DataType(DataType.Date)] public DateTime BirthDate { get; set; } [Range(8000, 10000)] [DataType(DataType.Currency)] public decimal Salary { get; set; }
DataType
特性只用于视图引擎对数据进行格式化(以及为URL提供 <a>
标签和为Email提供 <a href="mailto:EmailAddress.com">
)。你可以使用 RegularExpression
特性验证数据的格式。 DataType
特性用于指定比数据库本身类型更为具体的数据类型,它们不是验证特性,这本例中,我们只需要跟踪日期,而不需要具体的时间。
在 DataType
枚举中提供了很多的数据类型,例如Date, Time, PhoneNumber, Currency, EmailAddress等。 DataType
特性可以让应用自动提供特定数据类型的特征。例如, DataType.EmailAddress
可以创建 mailto:
链接, DataType.Date
可以在浏览器提供一个日期选择器。 DataType
特性会产生HTML 5浏览器所支持的HTML 5 data-
属性。 DataType
不提供任何验证。
DataType.Date
不是指定日期的显示格式。默认情况,数据字段默认的显示格式是基于服务器的 CultureInfo
设置来决定的。