在这本部分会将验证逻辑添加到Movie
模式,和你会确保验证规则执行任何时候用户试图创建或编辑使用应用程序的一部电影。
保持干燥
ASP.NET MVC 的核心设计原则之一就是干("不要重复你自己")。ASP.NET MVC 鼓励你只有一次,指定的功能或行为,然后它无处不在应用程序中反映。这减少了需要编写的代码量,并使你做编写更少错误倾向和易于维护的代码。
提供 ASP.NET MVC 和实体框架代码优先的验证支持是干燥原理在行动的很好的例子。你可以在一个地方 (在模型类) 以声明方式指定验证规则和无处不在应用程序中强制执行的规则。
让我们看看如何你可以利用这种验证支持的电影应用程序中。
向电影模型中添加验证规则
你会开始向Movie
类添加一些验证逻辑。
打开Movie.cs文件。通知System.ComponentModel.DataAnnotations
命名空间不包含System.Web
。DataAnnotations 提供了一组内置的验证特性,您可以以声明方式适用于任何类或属性。(它还包含像数据类型的格式属性,帮助与格式,不提供任何验证)。
现在更新Movie
类能够利用内置的Required
、 StringLength
、正则表达式和Range
验证属性。Movie
类替换为以下内容︰
public class Movie { public int ID { get; set; } [StringLength(60, MinimumLength = 3)] public string Title { get; set; } [Display(Name = "Release Date")] [DataType(DataType.Date)] [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] 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; } }
StringLength
属性设置字符串的最大长度和它在数据库上设置此限制,因此数据库架构将发生更改。右键点击电影表在服务器资源管理器中,单击打开表定义:
在上面的图片,你可以看到所有字符串字段都设置为NVARCHAR (最大)。我们将使用迁移来更新架构。生成解决方案,然后打开程序包管理器控制台窗口并输入以下命令︰
add-migration DataAnnotations
update-database
当此命令完成,Visual Studio 打开具有指定的名称 (DataAnnotations
),定义了新的DbMIgration
派生类的类文件并在Up
的方法,你可以看到代码更新架构约束︰
public override void Up() { AlterColumn("dbo.Movies", "Title", c => c.String(maxLength: 60)); AlterColumn("dbo.Movies", "Genre", c => c.String(nullable: false, maxLength: 30)); AlterColumn("dbo.Movies", "Rating", c => c.String(maxLength: 5)); }
Genre
字段是不再是可以为 null (即,您必须输入一个值)。Rating
字段的最大长度为 5 和Title
的最大长度为 60。在Title
上的 3 和Price
范围的最小长度未创建架构更改。
检查电影架构︰
字符串字段显示新的长度限制和Genre
已不再签可以为 null。
验证属性指定您想要在将它们应用于模型属性上实施的行为。 Required
和MinimumLength
属性指示的属性必须具有一个值;但没有什么可以防止用户输入的空格来满足这种验证。正则表达式属性用来限制字符可以是输入。在上面的代码,Genre
和Rating
必须使用只有字母 (不允许白色空间,数字和特殊字符)。Range
属性约束对指定范围内的值。StringLength
属性允许您设置一个字符串属性的最大长度和 (可选) 其最小长度。值类型 (例如decimal, int, float, DateTime
) 本身就需要和不需要的Required
属性。
代码首先确保你对模型类指定的验证规则执行之前应用程序将更改保存在数据库中。例如,下面的代码将抛出DbEntityValidationException异常SaveChanges
方法调用时,因为几个缺少必需的Movie
属性值︰
MovieDBContext db = new MovieDBContext(); Movie movie = new Movie(); movie.Title = "Gone with the Wind"; db.Movies.Add(movie); db.SaveChanges(); // <= Will throw server side validation exception
上面的代码会引发下列异常︰
对一个或多个实体验证失败。请参阅更多的细节的 'EntityValidationErrors' 属性。
验证规则会自动执行由.NET 框架有助于使您的应用程序更加健壮。它还确保,你不能忘验证一些东西,无意中让坏的数据到数据库。
验证错误在 ASP.NET MVC 中的 UI
运行应用程序并定位到/Movies的 URL。
单击创建新链接添加一部新电影。填写一些无效的值。JQuery 客户端验证检测到错误,它将显示一条错误消息。
请注意如何形式已自动用于红色边框的颜色突出显示文本框中包含无效数据和已发出旁边每一个适当的验证错误消息。错误强制执行 (使用 JavaScript 和 jQuery) 客户端和服务器端 (以防用户已禁用 JavaScript)。
真正的好处是,您不需要更改一行代码在MoviesController
类中或在Create.cshtml视图中,使这种验证 UI。控制器和你早些时候自动捡起你使用验证属性上Movie
模式类的属性指定的验证规则本教程中创建的视图。应用测试验证使用Edit
的操作方法和相同的验证。
直到有没有客户端验证错误表单数据不会发送到服务器。你可以通过把一个破发点在 HTTP Post 方法中,通过使用提琴手工具或 IE F12 开发人员工具来验证这.
如何验证发生在创建查看和创建操作方法
你可能想知道如何验证用户界面生成没有任何更新的控制器或视图中的代码。下一个清单显示MovieController
类中的 Create
方法是什么样子。他们从早些时候在本教程中创建的如何保持不变。
public ActionResult 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 ActionResult Create([Bind(Include = "ID,Title,ReleaseDate,Genre,Price,Rating")] Movie movie) { if (ModelState.IsValid) { db.Movies.Add(movie); db.SaveChanges(); return RedirectToAction("Index"); } return View(movie); }
第一次 (HTTP GET)Create
操作方法显示初始创建窗体。第二个 ([HttpPost]
) 版本处理窗体发布。第二种Create
方法 ( HttpPost
版) 调用ModelState.IsValid
来检查是否这部电影的任何验证错误。调用此方法的计算结果已应用于该对象的任何验证属性。如果对象具有验证错误,则Create
方法重新显示窗体。如果没有错误,该方法在数据库中保存新的电影。在我们电影的示例中,检测到; 客户端上的验证错误时不向服务器发送窗体第二Create
永远不会调用方法。如果您在您的浏览器中禁用 JavaScript,禁用客户端验证和 HTTP POSTCreate
方法调用ModelState.IsValid
来检查是否这部电影的任何验证错误。
您可以在HttpPost Create
方法中设置断点并验证永远不会调用该方法,客户端验证将不提交表单数据时检测到验证错误。如果您在您的浏览器中禁用 JavaScript,然后提交具有错误的窗体,将命中破发点。你仍然得到充分验证没有 JavaScript。下图显示如何禁用 JavaScript 互联网资源管理器中。
下图显示如何在火狐浏览器中禁用 JavaScript。
下图显示如何在 Chrome 浏览器中禁用 JavaScript。
![](https://media-www-asp.azureedge.net/media/46597/chrome.png)
下面是您搭建教程中早些时候的Create.cshtml视图模板。如上所示两个操作方法使用显示初始窗体,并在出现错误时重新显示它。
@model MvcMovie.Models.Movie @{ ViewBag.Title = "Create"; } <h2>Create</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>Movie</h4> <hr /> @Html.ValidationSummary(true) <div class="form-group"> @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Title) @Html.ValidationMessageFor(model => model.Title) </div> </div> @*Fields removed for brevity.*@ <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> } <div> @Html.ActionLink("Back to List", "Index") </div> @section Scripts { @Scripts.Render("~/bundles/jqueryval") }
请注意代码如何使用 Html.EditorFor
帮助器输出的每个Movie
属性的<input>
元素。此帮助器旁边是对Html.ValidationMessageFor
帮助器方法的调用。这两个帮助器方法处理由控制器传递到视图 (在这种情况下,Movie
对象) 的模型对象。他们会自动查找上作为适当的模型并显示错误消息指定的验证属性。
对这种做法非常好的是,控制器和Create
视图模板都不知道任何有关正在执行的实际验证规则或显示的特定错误消息。在Movie
类仅指定了验证规则和错误字符串。这些相同的验证规则会自动应用到Edit
视图和任何其他视图模板可以创建,编辑您的模型。
如果你想要在以后更改的验证逻辑,你可以在一个地方通过将验证属性添加到模型 (在此示例中,movie
课)。你不必担心不符合规则 》 如何强制执行的应用程序的不同部分 — — 所有的验证逻辑会在一个地方定义和使用无处不在。这使代码非常干净,并使它容易维护和发展。它意味着你会充分尊重DRY原则。
使用数据类型属性
打开Movie.cs文件并检查Movie
类。 System.ComponentModel.DataAnnotations
命名空间提供了内置的验证属性集的格式属性。我们已应用一个DataType
的枚举值的发布日期和价格字段。下面的代码演示的ReleaseDate
和Price
属性与相应的DataType
属性。
[DataType(DataType.Date)] public DateTime ReleaseDate { get; set; } [DataType(DataType.Currency)] public decimal Price { get; set; }
数据类型属性仅提供视图引擎来设置数据的格式的提示 (和供 URL 的属性,例如<a>
和<a href="mailto:EmailAddress.com">
的电子邮件。你可以使用正则表达式属性来验证数据的格式。数据类型属性用来指定比数据库内部类型更加具体的数据类型,它们不是验证属性。在这种情况下,我们只想要跟踪的日期,不是日期和时间。数据类型枚举提供的许多数据类型,如日期、 时间、 电话号码、 货币、 电子邮件地址和更多。DataType
属性也可以启用应用程序自动提供特定于类型的功能。例如, mailto:
为DataType.EmailAddress,可以创建链接和一个日期选择器可以为DataType.Date提供支持HTML5的浏览器。数据类型属性发出 HTML 5 的浏览器能理解的 HTML 5数据- (发音数据破折号) 属性。数据类型属性不能提供任何验证。
DataType.Date
未指定的日期的显示格式。默认情况下,根据基于服务器的CultureInfo的默认格式显示的数据字段.
DisplayFormat
属性用于显式指定的日期格式︰
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] public DateTime EnrollmentDate { get; set; }
ApplyFormatInEditMode
设置指定值显示在文本框中进行编辑时,应该也应用指定的格式。(您可能不希望一些领域 — — 例如,货币值,您可能不希望在文本框中的货币符号编辑。)
你可以使用DisplayFormat属性本身,但它通常是一个好的主意也使用该数据类型的属性。DataType
属性传递语义的数据而不是如何呈现在屏幕上,并提供以下好处,你不要跟DisplayFormat
:
- 浏览器可以启用 HTML5 功能 (例如显示一个日历控件,区域设置适当的货币符号,电子邮件链接,等等.)。
- 默认情况下,浏览器将呈现使用基于您的区域设置的正确格式的数据.
- 数据类型属性可以使 MVC 选择权字段模板来呈现的数据 (如果使用了DisplayFormat使用字符串模板)。有关详细信息,请参阅布拉德 · 威尔逊ASP.NET MVC 2 模板。(虽然为 MVC 2 写,这篇文章仍适用于当前版本的 ASP.NET MVC。)
如果你使用日期字段的DataType
属性,你必须也指定 DisplayFormat
属性,以确保该字段在 Chrome 浏览器中都能正确呈现。更多的信息,请参阅此计算器线程.
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]您将需要禁用 jQuery 日期验证与日期时间使用范围属性。通常,这不是很好的做法编译硬日期在您的模型,所以使用范围的属性和日期时间气馁的问题。
下面的代码显示在一行上结合属性︰
public class Movie { public int ID { get; set; } [Required,StringLength(60, MinimumLength = 3)] public string Title { get; set; } [Display(Name = "Release Date"),DataType(DataType.Date)] public DateTime ReleaseDate { get; set; } [Required] public string Genre { get; set; } [Range(1, 100),DataType(DataType.Currency)] public decimal Price { get; set; } [Required,StringLength(5)] public string Rating { get; set; } }
在本系列的下一部分,我们会审查适用,并作了一些改进的自动生成的Details
和 Delete
方法。
-----------------------------------------------------------------------------------------
《ASP.NET MVC 5 入门指南》12篇文章汇总如下:
5. ASP.NET MVC 5 - 创建连接字符串(Connection String)并使用SQL Server LocalDB
7. ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view)
8. ASP.NET MVC 5 - 将数据从控制器传递给视图
10. ASP.NET MVC 5 - 给电影表和模型添加新字段
11. ASP.NET MVC 5 - 给数据模型添加校验器
12. ASP.NET MVC 5 - 查询Details和Delete方法
希望这些文章对感兴趣的朋友有所帮助