给模型(Model)添加验证(ASP.NET MVC3系列文章八)

来源:互联网 发布:物业收费软件下载 编辑:程序博客网 时间:2024/05/17 04:41

 

原址:http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/getting-started-with-mvc3-part8-cs

 

这个教程将会使用Microsoft Visual Web Developer 2010 Express Service Pack 1来教会您构建一个基于ASP.NET MVC Web应用。 在您开始之前,请确保已经安装了下面罗列的必备条件。您可以点击接下来的链接来下载它们:Web Platform Installer。或者您可以使用下面的链接来单个安装:

  • Visual Studio Web Developer Express SP1 prerequisites
  • ASP.NET MVC 3 Tools Update
  • SQL Server Compact 4.0(runtime + tools support)

如果您使用的是Visual Studio 2010, 可以点击接下来的链接来安装这些必备条件: Visual Studio 2010 prerequisites.

在这个Visual Web Developer项目中将会全程使用c#. Download the C# version.。如果您比较擅长VB, 可以在这个教程中改为VB Visual Basic version

 

 

 

 

 

在这次章节中,您将会给Movie模型添加验证逻辑以确保在应用中用户试图执行添加或修改电影时,能得到有效验证。

保持DRY原则

ASP.NET MVC中的一个核心设计原则是DRY(Don't Repeat Yourself)--不要重复自己。ASP.NET MVC鼓励您对功能或行为仅仅指定一次就可以反映到一个应用中的任何地方,这减少了您需要书写的大量的代码而且更易于维护。

这个验证得到了ASP.NET MVC的支持并且Entity Framework的"Code First"模式是一个DRY实践的很好例子。您可以在一个地方(在模型类中)指定验证规则,并且这些规则在应用的任何地方都会被执行。

让我们来看看您怎样才能使用这种优势去验证电影信息。

给Movie模型(Model)添加验证规则

您将会开始向Movie类中添加一些验证逻辑。

打开Movie.cs 文件,在文件的顶部添加一个using声明来引用System.ComponentModel.DataAnnotations命名空间:

using System.ComponentModel.DataAnnotations;

这个命名空间是.NET Framework的一部分,他提供了一个内部的验证设置属性,这样您就可以把这种特性应用到任何类或属性上。

现在更新Movie类,给属性增加内建的Required,StringLengthRange 验证。修改后的代码如下所示。

public class Movie {     public int ID { get; set; }      [Required(ErrorMessage = "Title is required")]     public string Title { get; set; }      [Required(ErrorMessage = "Date is required")]     public DateTime ReleaseDate { get; set; }      [Required(ErrorMessage = "Genre must be specified")]     public string Genre { get; set; }      [Required(ErrorMessage = "Price Required")]     [Range(1, 100, ErrorMessage = "Price must be between $1 and $100")]     public decimal Price { get; set; }      [StringLength(5)]     public string Rating { get; set; } }


 

这个验证属性指定了在模型(model)属性上应用了这些行为。这个Required 属性指明了这个属性必须有一个值;在这个例子中,一部电影必须有标题,发售日期,类型和价格,所以这些属性使用了Required属性验证。这个Range属性约束了一个值在一个指定的范围以内。这个StringLength属性让您设置了字符串的最大长度并且最小长度是非必要的。

"Code First"确保了应用中的改变被保存到数据库之前,一个模型(model)类上指定的验证规则会被执行。例如,当SaveChanges方法被调用时,下面的代码将会抛出一个异常 ,这是由于几个必须输入的属性值为空并且价格属性是0(不符合range验证规则)。

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 validation exception

.NET Framework帮助您的应用程序自动的去执行了这些验证规则,用来避免您忘记了去做验证,而让一些糟糕的数据保存到数据库中。

这个是Movie.cs 文件完成后的代码:

using System; using System.Data.Entity; using System.ComponentModel.DataAnnotations;  namespace MvcMovie.Models {     public class Movie     {         public int ID { get; set; }          [Required(ErrorMessage = "Title is required")]         public string Title { get; set; }          [Required(ErrorMessage = "Date is required")]         public DateTime ReleaseDate { get; set; }          [Required(ErrorMessage = "Genre must be specified")]         public string Genre { get; set; }          [Required(ErrorMessage = "Price Required")]         [Range(1, 100, ErrorMessage = "Price must be between $1 and $100")]         public decimal Price { get; set; }          [StringLength(5)]         public string Rating { get; set; }     }      public class MovieDBContext : DbContext     {         public DbSet<Movie> Movies { get; set; }     } }


 

在ASP.NET MVC里验证一个错误UI

重新启动应用并且导航到/Movies URL。

点击Create Movie链接去添加一部新的电影,在点击Create按钮后,表单上出现了一些验证信息。

8_validationErrors

注意到这个表单有自动的使用了一个背景色去高亮了文本框并且在每个文本框的附近显示了相应的错误信息。错误信息匹配到您指定的错误字符串,这个错误是执行了客户端(使用JavaScript)和服务端(在这个例子中用户使用了JavaScript disabled)。

一个实际的好处是,您不需要改变MoviesController类的代码或者在Create.cshtml 视图(view)中来书写验证UI。这个控制器(controller)和视图(view)在早期的教程中已经自动添加,为了增加验证规则,您只需要在Movie模型(model)类中指定验证属性就可以了。

在Create视图和Create的Action方法中怎么发生验证

您可能想要知道在没有修改视图(view)或控制器(controller)中的任何代码,验证UI是怎么被生成的,接下来的列表展示了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); }

第一个action方法显示初始化的Create表单,第二个方法处理表单的POST请求,第二个Create方法调用了ModelState.IsValid去检查是否这部电影有任何的验证错误,调用这个方法评估了任何已经应用到对象上的验证属性,如果这个对象有验证错误,Create方法重新显示表单,如果没有错误,这个方法把新的电影保存到数据库中。

下面是您在更早的教程中生成的Create.cshtml 视图(view)模板, 它根据action方法用了上面的两种做法,一种是显示初始化表单,一种是在错误事件中重新显示它。

@model MvcMovie.Models.Movie @{     ViewBag.Title = "Create"; } <h2>     Create</h2> <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></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帮助器(helper)为每个Moive属性输出<input>元素,在帮助器的下面是调用了Html.ValidationMessageFor方法,这两个帮助器方法服务于从控制器(controller)传到视图(view)的模型(model)对象(在这个例子中就是一个Movie对象),他们自动的查找在模型中(model)指定验证属性并且适当的显示错误信息。

关于使用这种方式真正好的地方是,有关被执行的实际的验证规则或有关指定错误的显示信息既不在这个控制器(controller)中也不在创建的视图(view)模板中。 这个验证规则和错误字符串仅仅在Movie类中被指定。

如果您之后想要改变这个验证逻辑,您能够在一个地方准确的做到这一点。您不想在应用程序的不同地方产生不一致,去担心验证规则是怎么被执行的—所有验证逻辑将会一次定义多次使用。这保持了代码的干净并且更易于维护和演变,这意味着完全的遵照了DRY原则。

格式化Movie模型(Model)属性

打开Movie.cs file文件,这个System.ComponentModel.DataAnnotations命名空间增加内建的验证设置属性来格式化属性。您将会应用这个DisplayFormat 属性和一个DataType 枚举值到ReleaseDate和价Price字段上。下面的代码展示了在ReleaseDate和Price属性上适当的添加了DisplayFormat属性:

         [DataType(DataType.Date)]          public DateTime ReleaseDate { get; set; }                 [DataType(DataType.Currency)]          public decimal Price { get; set; }

作为选择,您可以明确的设置一个DataFormatString 值,下面的代码展示了给ReleaseDate属性附加一个日期格式化字符串(也就是"d").。您会使用这个方式来指定,是因为您不想要ReleaseDate属性的某些日期部分。

        [DisplayFormat(DataFormatString = "{0:d}")]        public DateTime ReleaseDate { get; set; }

下面的代码格式了当前的Price属性:

        [DisplayFormat(DataFormatString = "{0:c}")]        public decimal Price { get; set; }

完成后的类如下所示。

public class Movie {     public int ID { get; set; }      [Required(ErrorMessage = "Title is required")]     public string Title { get; set; }      [Required(ErrorMessage = "Date is required")]     [DisplayFormat(DataFormatString = "{0:d}")]     public DateTime ReleaseDate { get; set; }      [Required(ErrorMessage = "Genre must be specified")]     public string Genre { get; set; }      [Required(ErrorMessage = "Price Required")]     [Range(1, 100, ErrorMessage = "Price must be between $1 and $100")]     [DisplayFormat(DataFormatString = "{0:c}")]     public decimal Price { get; set; }      [StringLength(5)]     public string Rating { get; set; } }

启动应用和浏览器,链接到Movie 控制器(controller)。

8_format_SM

在这个系列文章的下一部分,我们将回顾一下这个应用程序并且做一些改善,自动的生成Details和Delete方法。

 

原创粉丝点击