ASP.NET Core 中文文档 第二章 指南(4.9)添加验证
原文:Adding Validation
作者:Rick Anderson
翻译:谢炀(Kiler)
校对:孟帅洋(书缘)、娄宇(Lyrics)、许登洋(Seay)
在本章节中你将为 Movie
模型类添加验证逻辑,以确保用户在试图创建或编辑影片数据时强制执行验证规则。
保持DRY原则
ASP.NET MVC 的核心原则之一是 DRY (“不要重复自己”)。ASP.NET MVC 鼓励你只指定一次行为或者功能,然后可以在应用程序里面到处使用,这样大大的减少了需要编写的代码量,并且使你编写不容易出错,更容易测试,以及更容易维护的代码。
ASP.NET MVC 和 Entity Framework Core Code First 中的验证功能,是 DRY 原则实际应用的一个很好的实例。你可以在某个位置(模型类)声明指定方式的验证规则,验证规则可以在整个应用程序中生效。
让我们来看看如何在电影应用程序中利用验证功能。
向 Movie 模型中添加验证规则
打开 Movie.cs 文件。DataAnnotations 提供了一组内置的验证特性,你可以对任何类或属性应用。(它也同时包含了一些格式化特性,比如 DataType
用来帮你格式化数据而非提供验证功能。)
现在修改 Movie
类,利用内置的 Required
、 StringLength
、RegularExpression
以及 Range
验证特性。
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; }
}
验证特性指定了你想要应用到模型属性上的验证行为。Required
以及 MinimumLength
特性表示属性不能为空,但无法阻止用户用填写空格的方式来满足此验证条件。RegularExpression
特性用来限制用户输入的文字类型。 在上面的例子中,Genre
以及 Rating
只能输入字母(不允许输入空格、数字以及特殊字符)。Range
特性限制值在指定的范围内。StringLength
特性可让你设定字符串最大长度,以及最小长度(可选)。值类型(如decimal, int, float, DateTime) 本身是必须的,并不需要 [Required]
特性。
ASP.NET 自动执行的验证规则将有助于使你的应用程序更加健壮。它还确保提醒你不要忘记验证数据,让非法数据进入到数据库中。
MVC 中的验证错误 UI
运行程序并导航到 Movies controller。
点击 Create New 链接创建一个新的 Movie。在表单中填写一些无效的数据,jQuery 客户端验证马上就会发现错误,立刻呈现到界面上。
注意
你也许无法在Price
字段中输入小数点或者逗号。为了让 jQuery validation 支持非英语环境使用逗号(",")代替小数点,以及非美式英语日期格式,你必须采取措施国际化你的应用程序。参考 附录资源 获取更多信息。 现在仅仅输入整数,比如 10。
请注意,表单在包含无效值的每个字段下自动呈现一个适当的验证错误消息。错误包括客户端(使用 JavaScript 和 jQuery )和服务器端(以防用户已禁用 JavaScript)。
一个显而易见的好处是,你并不需要改变 MoviesController
类或者 Create.cshtml 视图中的一行代码,就可以实现验证界面。你在本教程前面创建的控制器和视图,自动使用你指定的 Movie
模型类的属性上的验证特性的验证规则。使用 Edit
操作方法测试验证,(与Create 方法)同样的验证生效。
表单数据不会被发送到服务器直到没有客户端验证错误。你可以在 HTTP Post
方法中设置断点,并通过使用 Fiddler 工具或者 F12 开发者工具 访问这个方法来验证这一点。
创建视图和创建方法中如何触发验证
也许你会好奇生成的控制器或视图中的代码没有任何更新的情况下验证界面是如何产生的。下一个清单显示的是两个 Create
方法。
// GET: Movies/Create
public IActionResult Create()
{
return View();
}
// POST: Movies/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,Genre,Price,ReleaseDate,Title,Rating")] Movie movie)
{
if (ModelState.IsValid)
{
_context.Add(movie);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(movie);
}
第一个(HTTP GET) Create
的操作方法显示初始创建表单。第二个([HttpPost]
)版本的操作方法负责处理 post 请求。第二个 Create
的方法(HttpPost 版本)调用 ModelState.IsValid
检查是否有任何验证错误。调用该方法将检查任何已应用到对象属性上的验证。如果对象的 Create
方法验证错误,重新显示表单。如果没有错误,该方法在数据库中保存新的 movie。在我们的 movie 例子中,在客户端验证检测到错误时,表单将不会发送到服务器,第二个 Create 方法不会被调用。如果你的浏览器禁用了 JavaScript,客户端验证被禁用,HTTP POST 版本的 Create
方法调用 ModelState.IsValid
,以检查是否存在任何验证错误。
你可以在 [HttpPost] Create
方法中设置一个断点,用来验证该方法不会被调用,客户端验证发现错误时将不提交表单数据。如果你的浏览器禁用了 JavaScript ,然后提交有错误的表单,断点会被命中。不支持 JavaScript 的情况下,你仍然可以得到充分验证。下面的图片展示了如何在 IE 浏览器中禁用 JavaScript 脚本。
下面的图片展示了如何在 FireFox 浏览器中禁用 JavaScript 脚本。
下面的图片展示了如何在 Chrome 浏览器中禁用 JavaScript 脚本。
在禁用 JavaScript 脚本之后,post 非法数据并在调试器中单步调试。
下面是你在本教程前面用基架生成的 Create.cshtml 视图模板的一部分。它使用上面展示的两种 action 方法来显示初始表单并且在发生错误时重新显示。
<form asp-action="Create">
<div class="form-horizontal">
<h4>Movie</h4>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Genre" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Genre" class="form-control" /> <!--手工高亮-->
<span asp-validation-for="Genre" class="text-danger" /> <!--手工高亮-->
</div>
</div>
@*Markup removed for brevity.*@ <!--手工高亮-->
<div class="form-group">
<label asp-for="Rating" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Rating" class="form-control" /> <!--手工高亮-->
<span asp-validation-for="Rating" class="text-danger" /> <!--手工高亮-->
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
</form>
Input Tag Helper 消费 DataAnnotations 特性和产生jQuery验证所需要在客户端生成的 HTML 属性。Validation Tag Helper 负责显示错误信息。更多请参考 Validation 。
非常棒的是控制器和 Create
视图模板不知道实际执行的验证规则或显示的具体错误消息。只需要在 Movie
类里指定验证规则和错误字符串,同样的验证规则会自动应用到 Edit
视图和任何其他视图模板,你可以创建、编辑你的模型。
如果你想更改验证逻辑,你可以限定在一处地方(在本例中,是指 Movie 类),为模型添加验证特性。你不需要担心应用程序的不同部分执行的规则不一致 —— 所有的验证逻辑在同一个地方定义然后在各处使用 。这样可以使得代码很干净,而且易于维护和改进。这意味着,你充分遵循了 DRY 原则。
使用 DataType 特性
打开 Movie.cs 文件,并查看 Movie
类。System.ComponentModel.DataAnnotations
命名空间提供了除了内置的验证特性以外的一套格式化特性。我们已经应用了 DataType
枚举值到发布日期和价格字段。下面的代码显示了 ReleaseDate
和 Price
字段如何使用 DataType
特性。
[Display(Name = "Release Date")]
[DataType(DataType.Date)] //手工高亮
public DateTime ReleaseDate { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)] //手工高亮
public decimal Price { get; set; }
DataType
特性只用于视图引擎对数据进行格式化(或者提供给诸如 <A>
标签 的Url或者 <a href="mailto:EmailAddress.com">
提供的电子邮件),你可以使用 RegularExpression
特性来验证数据的格式,DataType
特性用于指定比数据库的自带类型更为具体的数据类型,它们不是验证特性,在本示例中我们只想跟踪日期,而不需要具体时间。在 DataType
枚举提供了许多数据类型,如日期、时间、手机号码、货币、电子邮件地址等。DataType
特性一样可以让应用程序具备自动提供特定数据类型的功能。例如,一个 mailto:
链接可以使用 DataType.EmailAddress
数据类型创建,在支持 Html5 的浏览器中并且日期选择器可以提供 DataType.Date
的值。DataType
特性向浏览器发送 HTML 5 标签 data-
(pronounced data dash)。DataType
特性 无法 提供任何验证。
DataType.Date
不指定日期的显示格式。默认情况下,数据字段默认的显示格式基于服务器的 CultureInfo
设置来决定的。
DisplayFormat
特性被用来格式化日期:
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }
ApplyFormatInEditMode
用来指定格式是否应用到文本框编辑。(你可能不希望在某些字段中使用这个功能——例如,对于货币值,你可能不希望在文本框中对货币符号进行编辑。)
你可以直接使用 DisplayFormat
特性本身,但是更好的方式是建议使用 DataType
, DataType
特性仅仅传递数据的语义,并不会通知浏览器如何呈现,如果不使用 DisplayFormat
有以下好处:
- 浏览器可以启用 HTML5 功能(例如显示日历控件,设置本地化的货币符号,电子邮件中的链接,等等)。
- 默认情况下,浏览器将基于你的 本地环境 使用正确的格式渲染数据。
DataType
特性可以使 MVC 选择正确的字段模板来呈现数据(比如DisplayFormat
如果单独使用 string 模板)。更多信息,请参考 Brad Wilson 的 ASP.NET MVC 2 模版。(尽管是为 MVC 2编写的, 文章依然适用于当前的 ASP.NET MVC 版本。)
注意
当Range
特性同时使用DateTime
类型的时候 jQuery 验证无法生效。例如,下面的代码将始终显示客户端验证错误,即使日期在指定范围内:
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]
你需要禁止在 DateTime
上使用 Range
特性来进行 JQuery 日期验证。在你的模型中编译具体日期通常不是一个好的做法,所以不建议在 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; }
}
在下一个系列里面, 我们会重新审视应用程序,为自动生成的 Details
以及 Delete
方法做一些提升。
附录资源
ASP.NET Core 中文文档 第二章 指南(4.9)添加验证的更多相关文章
- ASP.NET Core 中文文档 第二章 指南(4.6)Controller 方法与视图
原文:Controller methods and views 作者:Rick Anderson 翻译:谢炀(Kiler) 校对:孟帅洋(书缘) .张仁建(第二年.夏) .许登洋(Seay) .姚阿勇 ...
- ASP.NET Core 中文文档 第二章 指南(4.4)添加 Model
原文:Adding a model 作者:Rick Anderson 翻译:娄宇(Lyrics) 校对:许登洋(Seay).孟帅洋(书缘).姚阿勇(Mr.Yao).夏申斌 在这一节里,你将添加一些类来 ...
- ASP.NET Core 中文文档 第二章 指南 (09) 使用 Swagger 生成 ASP.NET Web API 在线帮助测试文档
原文:ASP.NET Web API Help Pages using Swagger 作者:Shayne Boyer 翻译:谢炀(kiler) 翻译:许登洋(Seay) 对于开发人员来说,构建一个消 ...
- ASP.NET Core 中文文档 第二章 指南(1)用 Visual Studio Code 在 macOS 上创建首个 ASP.NET Core 应用程序
原文:Your First ASP.NET Core Application on a Mac Using Visual Studio Code 作者:Daniel Roth.Steve Smith ...
- ASP.NET Core 中文文档 第二章 指南(2)用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API
原文:Building Your First Web API with ASP.NET Core MVC and Visual Studio 作者:Mike Wasson 和 Rick Anderso ...
- ASP.NET Core 中文文档 第二章 指南(3)用 Visual Studio 发布一个 Azure 云 Web 应用程序
原文:Getting Started 作者:Rick Anderson 翻译:谢炀(Kiler) 校对:孟帅洋(书缘).刘怡(AlexLEWIS).何镇汐 设置开发环境 安装最新版本的 Azure S ...
- ASP.NET Core 中文文档 第二章 指南(4.1)ASP.NET Core MVC 与 Visual Studio 入门
原文:Getting started with ASP.NET Core MVC and Visual Studio 作者:Rick Anderson 翻译:娄宇(Lyrics) 校对:刘怡(Alex ...
- ASP.NET Core 中文文档 第二章 指南(4.5)使用 SQL Server LocalDB
原文:Working with SQL Server LocalDB 作者:Rick Anderson 翻译: 魏美娟(初见) 校对: 孟帅洋(书缘).张硕(Apple).许登洋(Seay) Appl ...
- ASP.NET Core 中文文档 第二章 指南(5) 在 Nano Server 上运行ASP.NET Core
原文 ASP.NET Core on Nano Server 作者 Sourabh Shirhatti 翻译 娄宇(Lyrics) 校对 刘怡(AlexLEWIS).许登洋(Seay).谢炀(kile ...
随机推荐
- Linux CentOS 配置JDK环境
一.下载JDK 下载JDK的方式有两种: 1.Linux中使用wget下载 1.使用命令安装wget yum install wget 2.下载 wget 'http://download.oracl ...
- MVVM TextBox的键盘事件
MVVM下RichTextBox的键盘回车事件设置为发送,不是回车 xmlns:i="http://schemas.microsoft.com/expression/2010/interac ...
- AI人工智能系列随笔:syntaxnet 初探(1)
人工智能是 最近的一个比较火的名词,相信大家对于阿尔法狗都不陌生吧?其实我对人工智能以前也是非常抵触的,因为我认为机器人会取代人类,成为地球乃至宇宙的霸主,但是人工智能带给我的这种冲击,我个人感觉是欲 ...
- C# 用SoapUI调试WCF服务接口(WCF中包含用户名密码的验证)
问题描述: 一般调试wcf程序可以直接建一个单元测试,直接调接口. 但是,这次,我还要测试在接口内的代码中看接收到的用户名密码是否正确,所以,单一的直接调用接口方法行不通, 然后就想办法通过soapU ...
- 满堂红CIO邓劲翔:房屋中介突围
人脸识别.客户关系管理进度监控.业务流程实时监控.网站访问人数及流量实时监控等实际企业应用场景淋漓尽致.羽羽如生的以大屏幕上图表形式展现在人们面前,如果你不去继续询问,你不会知道这是一家才刚刚在房地产 ...
- Android的Kotlin秘方(II):RecyclerView 和 DiffUtil
作者:Antonio Leiva 时间:Sep 12, 2016 原文链接:http://antonioleiva.com/recyclerview-diffutil-kotlin/ 如你所知,在[支 ...
- SQL Server 2014聚集列存储索引
转发请注明引用和原文博客(http://www.cnblogs.com/wenBlog) 简介 之前已经写过两篇介绍列存储索引的文章,但是只有非聚集列存储索引,今天再来简单介绍一下聚集的列存储索引,也 ...
- NV显卡Ubuntu14.04更新软件导致登录死循环,不过可以进入tty模式
注意:此方法只适用于nv显卡的电脑! 在网上寻找各种方法无果的情况下,选择重新安装显卡驱动,成功登录进入图形界面. 一.首先需要在另外一台电脑(windows系统也可以)上下载NVIDIA相应显卡驱动 ...
- Spring MVC重定向和转发以及异常处理
SpringMVC核心技术---转发和重定向 当处理器对请求处理完毕后,向其他资源进行跳转时,有两种跳转方式:请求转发与重定向.而根据要跳转的资源类型,又可分为两类:跳转到页面与跳转到其他处理器.对于 ...
- ReSharper详解Index0
JetBrains ReSharper可以帮助Visual Studio用户编写出更好的代码.支持对C#,VB.NET,XAML,JavaScript,TypeScript,JSON,XML,HTML ...