https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/razor-pages/validation
每当用户创建或编辑电影时,都会强制执行验证规则。
验证
DRY 使代码更加不易出错,且更易于测试和维护。
验证规则在模型类中的某处以声明方式指定,且在应用的所有位置强制执行。
将验证规则添加到电影模型
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)] 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-Z""'\s-]*$")] [StringLength(5)] [Required] public string Rating { get; set; } }
验证特性用于指定模型属性上强制执行的行为:
- 值类型(如
decimal、int、float和DateTime),但不需要Required特性。 - 在上述代码中,
Genre和Rating仅可使用字母(禁用空格、数字和特殊字符)。 Range特性将值限制在指定范围内。StringLength特性设置字符串的最大长度,且可视情况设置最小长度。
自动验证模型有助于保护应用,因为添加新代码时无需手动应用它们。
Razor 页面中的“验证错误”UI
运行应用并导航到“页面/电影”。
当 jQuery 客户端验证检测到错误时,会显示一条错误消息。
备注
目前只能输入整数,例如 10。
客户端(使用 JavaScript 和 jQuery)和服务器端(若用户禁用 JavaScript)都必定会遇到这些错误。
使用“编辑”页面测试验证后,即已应用相同验证。
请通过以下一种或多种方法验证是否未发布表单数据:
- 从未命中断点。
- Fiddler 工具。
- 使用浏览器开发人员工具监视网络流量。
服务器端验证
在浏览器中禁用 JavaScript 后,提交出错表单将发布到服务器。
(可选)测试服务器端验证:
- 如果无法在浏览器中禁用 JavaScript,请尝试其他浏览器。
- 在“创建”或“编辑”页面的
OnPostAsync方法中设置断点。 - 提交带有验证错误的表单。
-
验证模型状态是否无效:
if (!ModelState.IsValid) { return Page(); }
它用于在“创建”和“编辑”页面中显示初始表单并在发生错误后重新显示表单。
<form method="post"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="Movie.Title" class="control-label"></label> <input asp-for="Movie.Title" class="form-control" /> <span asp-validation-for="Movie.Title" class="text-danger"></span> </div>
验证。
这些验证规则将自动应用于编辑 Movie 模型的 Razor 页面。
单处验证有助于保持代码干净,且更易于维护和更新。
使用 DataType 特性
DataType 特性应用于 ReleaseDate 和 Price 属性。
[Display(Name = "Release Date")] [DataType(DataType.Date)] public DateTime ReleaseDate { get; set; } [Range(1, 100)] [DataType(DataType.Currency)] public decimal Price { get; set; }
示例应用程序中仅显示日期,不显示时间。
DataType 特性不提供任何验证。
默认情况下,数据字段根据基于服务器的 CultureInfo 的默认格式进行显示。
DisplayFormat 特性用于显式指定日期格式:
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] public DateTime ReleaseDate { get; set; }
例如,在货币值中,可能不希望编辑 UI 中存在货币符号。
DataType 特性传达数据的语义而不是传达如何在屏幕上呈现数据,并提供 DisplayFormat 不具备的以下优势:
- 浏览器可启用 HTML5 功能(例如显示日历控件、区域设置适用的货币符号、电子邮件链接等)
- 默认情况下,浏览器将根据区域设置采用正确的格式呈现数据。
- 单独使用时,
DisplayFormat特性将使用字符串模板。
例如,以下代码将始终显示客户端验证错误,即便日期在指定的范围内:
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]
通常,在模型中编译固定日期是不恰当的,因此不推荐使用 Range 特性和 DateTime。
以下代码显示组合在一行上的特性:
public class Movie { public int ID { get; set; } [StringLength(60, MinimumLength = 3)] public string Title { get; set; } [Display(Name = "Release Date"), DataType(DataType.Date)] public DateTime ReleaseDate { get; set; } [RegularExpression(@"^[A-Z]+[a-zA-Z""'\s-]*$"), Required, StringLength(30)] public string Genre { get; set; } [Range(1, 100), DataType(DataType.Currency)] public decimal Price { get; set; } [RegularExpression(@"^[A-Z]+[a-zA-Z""'\s-]*$"), StringLength(5)] public string Rating { get; set; } }