学习ASP.NET Core Razor 编程系列目录
学习ASP.NET Core Razor 编程系列二——添加一个实体
学习ASP.NET Core Razor 编程系列三——创建数据表及创建项目基本页面
学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面
学习ASP.NET Core Razor 编程系列五——Asp.Net Core Razor新建模板页面
学习ASP.NET Core Razor 编程系列六——数据库初始化
学习ASP.NET Core Razor 编程系列七——修改列表页面
学习ASP.NET Core Razor 编程系列八——并发处理
学习ASP.NET Core Razor 编程系列九——增加查询功能
学习ASP.NET Core Razor 编程系列十——添加新字段
学习ASP.NET Core Razor 编程系列十一——把新字段更新到数据库
本篇文章我们学习如何给 Book实体类添加校验规则。当用户进行创建或编辑书籍信息时,都会触发校验规则。
一、校验
软件开发中有一个主要原则被称为 DRY(即“不要自我重复”)。 Razor 页面鼓励进行只需要开发一次,这个功能就能在整个应用中使用,不需要重复开发,或复制粘贴。 DRY 有助于减少应用中的代码量。 DRY 使代码更加不易出错,且更易于测试和维护。
Razor 页面和 Entity Framework框架提供的校验是支持DRY 原则的极佳示例。 校验规则在实体类中的某处以声明方式指定,且在应用程序的所有位置强制执行。
二、在书籍实体类中添加校验规则
在Visual Studio 2017的解决方案资源管理器中,打开 Models\Book.cs 文件。 DataAnnotations 提供一组内置的校验规则特性,我们可以通过声明的方式应用于类或属性之上。 DataAnnotations 还包含 DataType 等格式特性,有助于格式设置但不提供验证。
现在我们来给Book 类使用 Required、StringLength、RegularExpression 和 Range 校验规则特性,代码如下所示。
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks; namespace RazorMvcBooks.Models
{ public class Book
{ public int ID { get; set; }
[Required]
[StringLength(, MinimumLength = )]
public string Name { get; set; }
[Display(Name = "出版日期")]
[DataType(DataType.Date)] public DateTime ReleaseDate { get; set; }
[Range(,)]
[DataType(DataType.Currency)]
public decimal Price { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z""'\s-]*$"), Required, StringLength()] public string Author { get; set; }
[Required]
public string Publishing { get; set; } }
}
校验特性用在实体类的属性上,并且将前端强制执行。
Required 和 MinimumLength 特性表示属性必须具有一个值。 但是,用户可以随时输入空格对可以为 null 的类型进行校验约束。 从本质上来说,对于不能为 null 的值类型(如 decimal、int、float 和 DateTime),可以不添加 Required 特性。
RegularExpression 特性限制用户可以输入的字符。 在上述代码中, Rating 只能输入字母(禁用空格、数字和特殊字符)。
Range 特性将值限制在指定范围内。
StringLength 特性设置字符串的最大长度,且可视情况设置最小长度。
让 ASP.NET Core 强制自动执行校验规则有助于提升应用程序的可靠性。 在实体类上进行自动校验助于保护应用程序,因为添加新代码时无需手动修改旧代码。
三、查看面中的校验信息
在Visual Studio 2017中按F5运行应用程序,并在浏览器中浏览到书籍列表页面。
在书籍列表页面,使用鼠标左键点击“Create”链接。在新建页面中的输入框中输入一些无效值。当jQuery客户端校验检测到错误时,它会显示一条错误消息。 如下图。
备注
你可能无法在 Price 字段中输入小数点或逗号。 若要使 jQuery 校验支持非英英语环境中使用逗号(“,”)表替小数点,以及使用非美式英语日期格式,你必须采取应用全球化设置来改变你的应用程序。
请注意,表单在包含无效值的每个字段下自动呈现一个适当的校验错误消息。错误包括客户端(使用 JavaScript 和 jQuery )和服务器端(当用户禁用JavaScript时)。
一项重要好处是,无需在“创建”或“编辑”页面中更改代码。 一量在在实体类上应用 DataAnnotations 后,即已启用校验UI。 本教程中自动创建的 Razor 页面自动选取了校验规则(使用Book类的属性上的校验特性)。 使用“编辑”页面测试验证后,所有应用这个Book类的页面都应用了相同校验规则。
存在客户端验证错误时,不会将表单数据提交到后台服务器。 你可以使用以下一种或多种方法验证是否未发布表单数据:
1) 在 OnPostAsync 方法中放置一个断点。 提交表单(选择“Create”或“Save”)。 从未命中断点。
2) 使用 Fiddler 工具。
3) 使用浏览器开发人员工具监视网络流量。
四、服务器端验证
首先我们在浏览器中禁用 JavaScript,即不进行客户端校验,然后把有错误的数据提交到后台服务器。
测试服务器端验证:
1. 在浏览器中禁用 JavaScript。 如果你的浏览器中无法禁用 JavaScript,请试试其他浏览器。
2. 在“新建”或“编辑”页面的 OnPostAsync 方法中设置断点。
3. 提交带有不符全校验规则的表单数据。
4. 查看一下OnPostAsync方法中是否有以下代码。
if (!ModelState.IsValid)
{
return Page();
}
5. 结果如下图。
以下代码显示了之前在本教程中设定其基架的“Create.cshtml”的一部分。 它用于在“创建”和“编辑”页面中显示初始表单并在发生错误后重新显示表单。
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Book.Name" class="control-label"></label>
<input asp-for="Book.Name" class="form-control" />
<span asp-validation-for="Book.Name" class="text-danger"></span>
</div>
输入辅助助手使用 DataAnnotations 特性并在客户端生成 jQuery 校验所需的 HTML 元素。 校验辅助助手用于显示校验错误。
“创建”和“编辑”页面中没有校验规则。 校验规则和错误字符串仅可在BOOK 类中指定。 这些校验规则将自动应用于编辑页面。
当需要修改校验逻辑时,也只能在该Book实体类中修改。 校验将始终在整个应用程序中应用(校验逻辑在一处定义)。 在一个地方进行校验有助于保持代码干净,且更易于维护和更新。
五、使用DataType特性
现在我们在Visual Studio 2017中修改Book类。 DataAnnotations除了提供一组内置的验证特性,System.ComponentModel.DataAnnotations 命名空间还提供格式特性。 我们来看一下DataType 特性应用于 ReleaseDate 和 Price 属性。代码如下。
[Display(Name = "出版日期")]
[DataType(DataType.Date)] public DateTime ReleaseDate { get; set; }
[Range(,)] [DataType(DataType.Currency)]
public decimal Price { get; set; }
DataType 特性仅提供相关提示来帮助视图引擎设置数据格式(例如向 URL 提供 <a> 和向电子邮件提供 <a href="mailto:test@163.com">)。 使用 正则表达式(RegularExpression)特性校验数据的格式。 DataType 特性用于指定比数据库内部类型更具体的数据类型。 DataType 特性不是校验特性。 示例应用程序中“出版日期”仅显示日期,不显示时间。
DtaType 枚举提供了多种数据类型,例如日期、时间、电话号码、货币、电子邮件地址等。 DataType特性的使用能够使应用程序自动提供特定数据类型的功能。 例如,可为 DataType.EmailAddress 创建 mailto: 链接。 如果浏览器支持 HTML5 ,DataType.Date类型浏览器将提供日期选择器,如下图。
DataType 特性发出 HTML 5 特性供 支持HTML 5 浏览器使用。 DataType 特性不提供任何校验。
DataType.Date 不指定显示日期的格式。 默认情况下,日期数据格式基于服务器的 CultureInfo 的默认格式进行显示。
DisplayFormat 特性用于显式指定日期格式:例如
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }
ApplyFormatInEditMode 设置用于指定在显示值进行编辑时需要显示的格式。 在某些场景中,您可能不希望某些字段具有此行为。 例如,在货币值中,可能不希望编辑 UI 中使用货币符号。
可单独使用 DisplayFormat 特性,但通常建议使用 DataType 特性。 DataType 特性传递数据的语义而不是传递如何在前端界面上呈现数据,DataType具体 DisplayFormat 不具备的以下优势:
- 浏览器如果支持HTML5,则会自动显示相应的一些控件与功能(例如显示日期控件、区域设置适用的货币符号、电子邮件链接等)。
- 默认情况下,浏览器将根据您在区域设置中设置的区域采用正确的格式呈现数据。
- DataType特性可以使ASP.NET Core框架可选择适当的字段模板来呈现数据。如果单独使用时,可以使用DisplayFormat 特性的显式的指定数据格式。
注:jQuery校验不能校验日期范围与日期时间。例如,在Book类中添加下面的代码,在浏览器中输入任何日期,都是显示校验错误,即使选择的日期是在指定的范围之内,如下图:
[Display(Name = "出版日期")]
[Range(typeof(DateTime), "1980/1/1", "2050/1/1")]
public DateTime ReleaseDate { get; set; }
通常,在实体类中设置固定日期是不合适的,因此不推荐使用 Range 特性和 DateTime特性。