本节内容:
向 Movie 模型添加了验证逻辑。
确保每当用户创建或编辑电影时,都会强制执行验证规则。
坚持 DRY 原则
MVC 的设计原则之一是 DRY(“不要自我重复”)。 ASP.NET Core MVC 支持你仅指定一次功能或行为,然后使它应用到整个应用中。 这可以减少所需编写的代码量,并使编写的代码更少出错,更易于测试和维护。
MVC 和 Entity Framework Core Code First 提供的验证支持是 DRY 原则在实际操作中的极佳示例。 可以在一个位置(模型类中)以声明方式指定验证规则,并且在应用中的所有位置强制执行。
将验证规则添加到电影模型
DataAnnotations 命名空间提供一组内置验证特性,可通过声明方式应用于类或属性。 DataAnnotations 还包含 DataType 等格式特性,有助于格式设置但不提供任何验证。
更新 Movie 类以使用内置的 Required、StringLength、RegularExpression 和 Range 验证特性。
public class Movie
{
public int Id { get; set; }
[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; }
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z""'\s-]*$")]
[Required]
[StringLength(30)]
public string Genre { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
[StringLength(5)]
[Required]
public string Rating { get; set; }
}
验证特性指定要对应用这些特性的模型属性强制执行的行为:
Required 和 MinimumLength 特性表示属性必须有值;但用户可输入空格来满足此验证。
RegularExpression 特性用于限制可输入的字符。 在上述代码中,即“Genre”(分类):
只能使用字母。
第一个字母必须为大写。 不允许使用空格、数字和特殊字符。
RegularExpression“Rating”(分级):
要求第一个字符为大写字母。
允许在后续空格中使用特殊字符和数字。 “PG-13”对“分级”有效,但对于“分类”无效。
Range 特性将值限制在指定范围内。
StringLength 特性使你能够设置字符串属性的最大长度,以及可选的最小长度。
从本质上来说,需要值类型(如 decimal、int、float、DateTime),但不需要 [Required] 特性。
让 ASP.NET Core 强制自动执行验证规则有助于提升你的应用的可靠性。 同时它能确保你无法忘记验证某些内容,并防止你无意中将错误数据导入数据库。
验证错误 UI
运行应用并导航到电影控制器。
点击“新建”连接添加新电影 的链接。 使用无效值填写表单。 当 jQuery 客户端验证检测到错误时,会显示一条错误消息。
备注
可能无法在小数字段中输入十进制逗号。 若要使 jQuery 验证支持使用逗号(“,”)表示小数点的的非英语区域设置,以及支持非美国英语日期格式,必须执行使应用全球化的步骤。 有关添加十进制逗号的说明,请参阅 GitHub 问题 4076。
请注意表单如何自动呈现每个包含无效值的字段中相应的验证错误消息。 客户端(使用 JavaScript 和 jQuery)和服务器端(若用户禁用 JavaScript)都必定会遇到这些错误。
明显的好处在于不需要在 MoviesController 类或 Create.cshtml 视图中更改单个代码行来启用此验证 UI 。 在本教程前面创建的控制器和视图会自动选取验证规则,这些规则是通过在 Movie 模型类的属性上使用验证特性所指定的。 使用 Edit 操作方法测试验证后,即已应用相同的验证。
存在客户端验证错误时,不会将表单数据发送到服务器。 可通过使用 Fiddler 工具或 F12 开发人员工具在 HTTP Post 方法中设置断点来对此进行验证。
验证工作原理
你可能想知道在不对控制器或视图中的代码进行任何更新的情况下,验证 UI 是如何生成的。 下列代码显示两种 Create 方法。
// GET: Movies/Create
public IActionResult Create()
{
return View();
}
// POST: Movies/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task
[Bind("ID,Title,ReleaseDate,Genre,Price, Rating")] Movie movie)
{
if (ModelState.IsValid)
{
_context.Add(movie);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(movie);
}
第一个 (HTTP GET) Create 操作方法显示初始的“创建”表单。 第二个 ([HttpPost]) 版本处理表单发布。 第二个 Create 方法([HttpPost] 版本)调用 ModelState.IsValid 以检查电影是否有任何验证错误。 调用此方法将评估已应用于对象的任何验证特性。 如果对象有验证错误,则 Create 方法会重新显示此表单。 如果没有错误,此方法则将新电影保存在数据库中。 在我们的电影示例中,在检测到客户端上存在验证错误时,表单不会发布到服务器。当存在客户端验证错误时,第二个 Create 方法永远不会被调用。 如果在浏览器中禁用 JavaScript,客户端验证将被禁用,而你可以测试 HTTP POST Create 方法 ModelState.IsValid 检测任何验证错误。
可以在 [HttpPost] Create 方法中设置断点,并验证方法从未被调用,客户端验证在检测到存在验证错误时不会提交表单数据。 如果在浏览器中禁用 JavaScript,然后提交错误的表单,将触发断点。 在没有 JavaScript 的情况下仍然可以进行完整的验证。
以下图片显示如何在 FireFox 浏览器中禁用 JavaScript。
以下图片显示如何在 Chrome 浏览器中禁用 JavaScript。
禁用 JavaScript 后,发布无效数据并单步执行调试程序。
Create.cshtml 视图模板的一部分在以下标记中显示 :
发表评论