==============================翻译==============================
在这本部分会将验证逻辑添加到Movie
模式,和你会确保,验证规则被强制用户尝试创建或编辑电影使用的应用程序的任何时间。
ASP.NET MVC 的核心设计信条之一是 DRY(”Don't Repeat Yourself“,不要重复)。ASP.NET MVC 鼓励你只有一次,指定功能或行为,然后让它无处不在应用程序中反映。这可以减少您需要编写的代码数量,并使你做编写较少的错误倾向和易于维护的代码。
ASP.NET MVC 和 Entity Framework Code First 中提供的验证支持就是操作中 DRY 原则的很好的例子。您可以以声明方式指定验证规则在一个地方 (模型类) 中,到处都在应用程序中执行的规则。
让我们看看如何您可以利用这种验证支持的在电影中的应用。
你就会开始向Movie
类添加一些验证逻辑。
打开Movie.cs文件。 System.ComponentModel.DataAnnotations
命名空间引用的文件的顶部添加一个using
语句:
using System.ComponentModel.DataAnnotations;
注意该命名空间不包含System.Web
。DataAnnotations 提供了一组内置的验证特性,你可以以声明方式适用于任何类或属性。
现在更新Movie
类利用内置的Required
、 StringLength
和Range
验证属性。使用下面的代码为例,应用属性的位置。
public class Movie { public int ID { get; set; } [Required] public string Title { get; set; } [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; } [StringLength(5)] public string Rating { get; set; } }
运行该应用程序,你会再次得到以下的运行的时错误:
我们将我们要更新 scheam 的迁移。生成解决方案,然后打开软件包管理器控制台窗口并输入以下命令:
add-migration AddDataAnnotationsMig
update-database
当此命令完成,Visual Studio 打开具有指定的名称 (AddDataAnnotationsMig),定义新的DbMIgration
派生的类的类文件并Up
的方法中,你可以看到代码的更新架构约束。Title
和Genre
字段不再是可以为 null (即,您必须输入一个值) 和Rating
字段的最大长度为 5。
验证属性指定您想要对它们应用于模型属性强制执行的行为。 Required
属性指示属性必须有一个值 ;在此示例中,一部电影都必须有Title
、 ReleaseDate
、Genre
和Price
属性的值,这样才有效。Range
属性限制到指定范围内的值。StringLength
属性允许您设置一个字符串属性的最大长度和 (可选) 其最小长度。(例如decimal, int, float, DateTime
) 的内部类型,默认情况下需要和不需要所Required
属性。
代码首先确保您指定模型的类的验证规则强迫之前该应用程序将更改保存在数据库中。例如,下面的代码在调用SaveChanges
方法时将引发异常,因为几个所需Movie
属性的值是失踪和价格是零 (这是超出有效范围)。
MovieDBContext db = new MovieDBContext(); Movie movie = new Movie(); movie.Title = "Gone with the Wind"; movie.Price = 0.0M; db.Movies.Add(movie); db.SaveChanges(); // <= Will throw server side validation exception
有由.NET 框架就会自动执行的验证规则可帮助让您的应用程序更可靠。它还确保你不能忘了验证的东西,无意中让坏的数据到数据库中。
这里是完整的代码列表更新的Movie.cs文件:
using System; using System.Data.Entity; using System.ComponentModel.DataAnnotations; namespace MvcMovie.Models { public class Movie { public int ID { get; set; } [Required] public string Title { get; set; } [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; } [StringLength(5)] public string Rating { get; set; } } public class MovieDBContext : DbContext { public DbSet<Movie> Movies { get; set; } } }
重新运行该应用程序,然后定位到/Movies的 URL。
单击创建新的链接来添加一部新电影。填写窗体的一些无效的值,然后单击创建按钮。
Globalize.parseFloat
。下面的代码演示对要与"FR-FR"文化工作的 Views\Movies\Edit.cshtml 文件的修改:
@section Scripts { @Scripts.Render("~/bundles/jqueryval") <script src="~/Scripts/globalize.js"></script> <script src="~/Scripts/globalize.culture.fr-FR.js"></script> <script> $.validator.methods.number = function (value, element) { return this.optional(element) || !isNaN(Globalize.parseFloat(value)); } $(document).ready(function () { Globalize.culture('fr-FR'); }); </script> <script> jQuery.extend(jQuery.validator.methods, { range: function (value, element, param) { //Use the Globalization plugin to parse the value var val = $.global.parseFloat(value); return this.optional(element) || ( val >= param[0] && val <= param[1]); } }); </script> }
请注意如何窗体已自动用红色边框的颜色来突出显示已发出适当的验证错误消息在每个并包含无效数据的文本框。错误,强制 (使用 JavaScript 和 jQuery) 客户端和服务器端执行,(以防用户已禁用 JavaScript)。
真正的好处是你不需要更改单个代码行,在MoviesController
类中或在Create.cshtml视图中,使这种验证用户界面。在控制器和你较早前在自动捡到的您使用验证特性上Movie
模型类别中的属性指定的验证规则本教程中创建的视图。
您可能已经注意到的属性的Title
和Genre
,所需的属性才强制你提交表单 (打创建按钮),或在输入字段中输入文本并删除它。为字段,最初是空 (如创建视图字段) 和具有唯一必需的属性并没有其他的验证属性,您可以执行以下操作来触发验证:
上面的顺序将触发必需的验证没有击中提交按钮。只击中提交按钮,而无需输入任何字段将触发客户端验证。直到有没有客户端验证错误的表单数据不是发送到服务器。您可以通过将断点放在 HTTP Post 方法或使用的提琴手工具或 IE 9 F12 开发人员工具测试这.
您可能想知道如何验证用户界面生成没有任何更新的控制器或视图中的代码。下一个列表显示中的MovieController
类的 Create
方法是什么样子。他们从如何创建他们较早前在本教程中不变。
// // GET: /Movies/Create public ActionResult Create() { return View(); } // // POST: /Movies/Create [HttpPost] public ActionResult Create(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 互联网资源管理器中。
下图显示了如何在 FireFox 浏览器中禁用 JavaScript。
下图显示了如何禁用 JavaScript 与 Chrome 浏览器。
下面是您启用了基架较早前在本教程中的Create.cshtml视图模板。以显示初始窗体并重新显示它在出现错误时,它是由两个以上所示的操作方法使用。
@model MvcMovie.Models.Movie @{ ViewBag.Title = "Create"; } <h2>Create</h2> <script src="@Url.Content("~/Scripts/jquery.validate.min.js")"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script> @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>Movie</legend> <div class="editor-label"> @Html.LabelFor(model => model.Title) </div> <div class="editor-field"> @Html.EditorFor(model => model.Title) @Html.ValidationMessageFor(model => model.Title) </div> <div class="editor-label"> @Html.LabelFor(model => model.ReleaseDate) </div> <div class="editor-field"> @Html.EditorFor(model => model.ReleaseDate) @Html.ValidationMessageFor(model => model.ReleaseDate) </div> <div class="editor-label"> @Html.LabelFor(model => model.Genre) </div> <div class="editor-field"> @Html.EditorFor(model => model.Genre) @Html.ValidationMessageFor(model => model.Genre) </div> <div class="editor-label"> @Html.LabelFor(model => model.Price) </div> <div class="editor-field"> @Html.EditorFor(model => model.Price) @Html.ValidationMessageFor(model => model.Price) </div> <div class="editor-label"> @Html.LabelFor(model => model.Rating) </div> <div class="editor-field"> @Html.EditorFor(model => model.Rating) @Html.ValidationMessageFor(model => model.Rating) </div> <p> <input type="submit" value="Create" /> </p> </fieldset> } <div> @Html.ActionLink("Back to List", "Index") </div>
请注意,代码如何使用Html.EditorFor
帮助器输出Movie
的每个属性的<input>
元素。此帮助器旁边是对Html.ValidationMessageFor
帮助器方法的调用。这两个帮助器方法工作由控制器传递到视图 (在这种情况下,Movie
对象) 中的模型对象。他们会自动查找适当的模型并显示错误消息中指定的验证属性。
有关这种方法真的很好的是既不在控制器,也不创建视图模板知道任何有关强制执行的实际验证规则或显示的特定的错误消息。只在Movie
类中指定的验证规则和错误字符串。这些相同的验证规则将自动应用到编辑视图和任何其他视图模板可以创建,编辑您的模型。
如果你想要在以后更改验证逻辑,你可以在一个地方通过将验证属性添加到模型 (在此示例中,movie
类)。你不必担心不符合规则 》 如何强制执行应用程序的不同部分 — — 将会在一个地方定义和使用到处所有验证逻辑。这使代码非常干净,并使它易于维护和发展。它意味着你会和充分尊重的干燥的原则。
打开Movie.cs文件并检查Movie
类。 System.ComponentModel.DataAnnotations
命名空间提供了内置的验证特性集的格式属性。我们已应用发布日期和价格字段的DataType
的枚举值。下面的代码演示的ReleaseDate
和Price
属性与相应的DisplayFormat
属性。
[DataType(DataType.Date)] public DateTime ReleaseDate { get; set; } [DataType(DataType.Currency)] public decimal Price { get; set; }
DataType
属性不是验证特性,它们被用来告诉如何呈现的 HTML 的视图引擎。在上面的示例中, DataType.Date
属性将日期的电影显示日期作为唯一的与出时间。例如,下面的DataType
属性不需要验证的数据的格式:
[DataType(DataType.EmailAddress)] [DataType(DataType.PhoneNumber)] [DataType(DataType.Url)]
上面列出的属性只提供视图引擎来设置数据的格式的提示 (和供应的属性如 < > 为 URL 的和 < href="mailto:EmailAddress.com"> 电子邮件。你可以使用正则表达式属性来验证数据的格式。
另一种方法使用的DataType
属性您可以显式设置一个DataFormatString
值。下面的代码显示具有日期格式字符串的释放日期属性 (即"d")。您将使用指定您不希望时间作为一部分的发行日期。
[DisplayFormat(DataFormatString = "{0:d}")] public DateTime ReleaseDate { get; set; }
下面的代码的格式设置为货币的Price
属性。
[DisplayFormat(DataFormatString = "{0:c}")] public decimal Price { get; set; }
下面显示了完整的Movie
类。
public class Movie { public int ID { get; set; } [Required] public string Title { get; set; } [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; } [StringLength(5)] public string Rating { get; set; } }
运行该应用程序并浏览到Movies
控制器。很好地格式化的发布日期和价格。下面的图像显示的发布日期和价格使用"FR-FR"作为文化。
下面的图像显示与默认区域性 (美国英语) 显示相同的数据。
在一系列的下一部分,我们会检查该应用程序并进行一些自动生成的Details
和 Delete
方法的改进。
==============================翻译==============================