原文 ASP.NET MVC 5 学习教程:添加验证

起飞网 ASP.NET MVC 5 学习教程目录:

在本节中,我们将为Movie模型添加验证逻辑,并确认验证规则在用户试图使用程序创建和编辑电影时有效。

DRY 原则

ASP.NET MVC 的一个核心原则是DRY(Don't Repeat Yourself - 不做重复的事情)。ASP.NET MVC 鼓励你一次性的指定功能或行为,然后应用程序的其它地方通过映射得到它,这样一来就减少了大量的代码,从而减少了出错误的可能性,并且更易于维护。

ASP.NET  MVC  和 Entity Framework Code First 提供的验证能是 DRY 原则的不错的实践。你可以在一处(在模型类中)定义验证规则,从而在应用程序中的所有地方都可以使用这个规则。

接下来让我们看看如何在现在的Movie 中添加高级的验证规则吧。

为模型添加验证规则

现在我们开始为Movie类添加一些验证规则。

打开文件 Movie.cs,注意命名空间 System.ComponentModel.DataAnnotations 并不包含 System.Web。DataAnnotations 提供了内置的验证特性,你可以将它们用在任何类或属性中(它还包含了像DataType这样的格式化的特性,它们不参与任何验证)。

为Movie类添加一些内置的验证规则,修改后的代码如下:

代码清单1:添加了验证规则的Movie类

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; } [StringLength(5)]
[Required]
public string Rating { get; set; }
}

使用数据迁移来更新数据库结构。编译解决方案,然后打开“程序包管理器控制台”窗口,执行下面的命令:

add-migration DataAnnotations
update-database

当这两个命令执行完成之后,Visual Studio 为我们创建了 DataAnnotations 类,它继承自 DbMigration。打开文件,在它的Up方法中,你会看到升级结构的代码:

代码清单2:升级数据库结构的Up方法

public override void Up()
{
AlterColumn("dbo.Movies", "Title", c => c.String(nullable: false, maxLength: 60));
AlterColumn("dbo.Movies", "Genre", c => c.String(nullable: false));
AlterColumn("dbo.Movies", "Rating", c => c.String(nullable: false, maxLength: 5));
}

从代码中可以看出,Title、Genre和Rating三个字段不再允许为空(这意味着你必须输入一个值)。Rating 字段的最大长度为5,Title 的最大长度为60,最小长度为3。

Code First 确保在保存到数据库的时候使用你指定的规则对数据进行验证,例如,下面的代码在调用SaveChanges的时候会抛出一个错误:

MovieDBContext db = new MovieDBContext();

Movie movie = new Movie();
movie.Title = "Gone with the Wind"; db.Movies.Add(movie);
db.SaveChanges(); // <= 会引发一个服务器段的错误,因为movie的必须的字段没有赋值

验证规则在保存的时候自动生效使得程序变得更为健壮,它可以在是你忘记去验证,而在不经意间阻止不合法的进入数据库。

ASP.NET MVC 客户端验证

运行应用程序,浏览地址 /movies,点击“Create New”链接添加一个电影。如果我们在输入过程中出现一些不合法的数据,客户端将会显示一些错误,这是通过 jQuery 客户端验证来实现的。下面是一些错误信息:

图1:客户端验证信息

当出现错误的时候,文本框会被加上红色的边框,并且会显示一段错误描述信息。这些错误信息可以在客户端(使用Javascript 和 jQuery)和服务器(当客户端Javascript无效时)段生效。

一个真正的好处是,你不需要在MoviesController 或 Create.cshtml 中修改一行代码来启用客户端验证,控制器和视图会根据我们之前定义在Movie类中的验证特性自动选择验证规则。

表单数据出现错误的时候不会被提交到服务器端。

验证是如何工作的

你可能会觉得奇怪,客户端验证是如何在没有修改控制器或视图代码的情况下生成的。下面的代码显示了MovieController的Create方法,它和我们前面的教程中的Create代码一样,并没有经过修改:

代码清单3:Create 方法

//
// GET: /Movies/Create
public ActionResult Create()
{
return View();
} //
// POST: /Movies/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Movie movie)
{
if (ModelState.IsValid)
{
db.Movies.Add(movie);
db.SaveChanges();
return RedirectToAction("Index");
} return View(movie);
}

第一个Create方法显示一个表单,第二个Create方法用来处理POST请求提交的表单数据。第二个Create方法调用 ModelState.IsValid来检查movie数据是否存在验证错误,调用这个方法来检查验证规则,如果存在错误,Create 方法将会重新显示这个表单,如果没有,则会将Movie数据保存到数据库。在我们的例子中,当验证出现错误的时候表单不会提交到服务器,第二个 Create方法将不会调用。如果你禁用了Javascript客户端验证,第二个Create方法则会调用ModelState.IsValid对数据 进行检查。

你可以通过在HttpPost Create 方法中添加断点来监视是否被调用。当客户端出现错误的时候表单将不会提交,如果我们禁用客户端的Javascript,表单将错误的数据提交到服务器,断 点将会跟踪到。下面我们介绍一下如何在IE和Google浏览器中禁用Javascript。

在 IE 中禁用Javascript

打开Internet选项,在安全选项中选中“本地Intranet”,点击“自定义级别”按钮:

图2:自定义安全级别

然后在安全设置窗口中,找到“活动脚本”,选择“禁用”:

图3:禁用活动脚本

点击“确定”按钮,然后跟踪你提交的数据:

图4:跟踪到未通过验证的数据

在火狐(FireFox)中禁用Javascript

图5:在火狐中禁用Javascript

在Google Chrome中禁用Javascript

图6:在Google Chrome 中禁用Javascript

下面是 Create.cshtml 视图的代码,它被控制器中的Create方法用来显示初始的form表单,或在发生错误时重新显示带错误信息的表单数据。

代码清单4:Create.cshtml

@model MvcMovie.Models.Movie

@{
ViewBag.Title = "Create";
} <h2>Create</h2> @using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true) <fieldset class="form-horizontal">
<legend>Movie</legend> <div class="control-group">
@Html.LabelFor(model => model.Title, new { @class = "control-label" })
<div class="controls">
@Html.EditorFor(model => model.Title)
@Html.ValidationMessageFor(model => model.Title, null, new { @class = "help-inline" })
</div>
</div> <div class="control-group">
@Html.LabelFor(model => model.ReleaseDate, new { @class = "control-label" })
<div class="controls">
@Html.EditorFor(model => model.ReleaseDate)
@Html.ValidationMessageFor(model => model.ReleaseDate, null, new { @class = "help-inline" })
</div>
</div> <div class="control-group">
@Html.LabelFor(model => model.Genre, new { @class = "control-label" })
<div class="controls">
@Html.EditorFor(model => model.Genre)
@Html.ValidationMessageFor(model => model.Genre, null, new { @class = "help-inline" })
</div>
</div> <div class="control-group">
@Html.LabelFor(model => model.Price, new { @class = "control-label" })
<div class="controls">
@Html.EditorFor(model => model.Price)
@Html.ValidationMessageFor(model => model.Price, null, new { @class = "help-inline" })
</div>
</div> <div class="control-group">
@Html.LabelFor(model => model.Rating, new { @class = "control-label" })
<div class="controls">
@Html.EditorFor(model => model.Rating)
@Html.ValidationMessageFor(model => model.Rating, null, new { @class = "help-inline" })
</div>
</div> <div class="form-actions no-color">
<input type="submit" value="Create" class="btn" />
</div>
</fieldset>
} <div>
@Html.ActionLink("Back to List", "Index")
</div> @section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

模型格式化输出

打开文件Movie.cs,检查Movie类,System.ComponentModel.DataAnnotations 命名空间除了一套内置的验证特性外,还提供了格式化特性。我们已经在ReleaseDate 和Price字段用到过DataType枚举,下面的代码展示了ReleaseDate和Price属性中使用的DisplayFormat特性:

代码清单5:使用了DisplayFormat的字段

[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; } [Range(1, 100)]
[DataType(DataType.Currency)]
public decimal Price { get; set; }

DataType特性不是验证特性,他们用来告诉试图引擎如何绘制HTML。在上面的例子中,DataType.Date 特性使ReleaseDate显示的时候只显示日期部分,而不显示时间。下面的DataType特性不验证数据的格式:

[DataType(DataType.EmailAddress)]
[DataType(DataType.PhoneNumber)]
[DataType(DataType.Url)]

这些特性只为试图引擎格式化显示数据时提供建议。你可以使用RegularExpression 特性连验证数据的格式。

除了使用现成的DataType 格式化特性之外,你还可以明确指定 DataFormatString 值。下面的代码展示了ReleaseDate属性使用格式化字符串的情况,你可以使用它来不显示ReleaseDate日期的时间部分:

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

下面的代码将Price显示为货币的格式:

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

完整的Movie类代码如下:

代码清单6:Movie类

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; } [StringLength(5)]
[Required]
public string Rating { get; set; }
}

下面的代码展示了如何将特性合并在一行显示:

代码清单7:合并特性后的Movie类

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 方法做一些改进。

本文同时发布在起飞网,原文地址:http://www.qeefee.com/mvc/mvc-5-adding-validation

 

如果认为此文对您有帮助,别忘了支持一下哦!

作者:齐飞
声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权,贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。

ASP.NET MVC 5 学习教程:添加验证的更多相关文章

  1. ASP.NET MVC 5 学习教程:数据迁移之添加字段

    原文 ASP.NET MVC 5 学习教程:数据迁移之添加字段 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符 ...

  2. ASP.NET MVC 5 学习教程:添加查询

    原文 ASP.NET MVC 5 学习教程:添加查询 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 通过控 ...

  3. ASP.NET MVC 5 学习教程:添加模型

    原文 ASP.NET MVC 5 学习教程:添加模型 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 通过控 ...

  4. ASP.NET MVC 5 学习教程:添加视图

    原文 ASP.NET MVC 5 学习教程:添加视图 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 通过控 ...

  5. ASP.NET MVC 5 学习教程:添加控制器

    原文 ASP.NET MVC 5 学习教程:添加控制器 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 通过 ...

  6. ASP.NET MVC 5 学习教程:快速入门

    起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 通过控制器访问模型的数据 生成的代码详解 使用 SQL Se ...

  7. ASP.NET MVC 5 学习教程:Details 和 Delete 方法详解

    原文 ASP.NET MVC 5 学习教程:Details 和 Delete 方法详解 在教程的这一部分,我们将研究一下自动生成的 Details 和Delete 方法. Details 方法 打开M ...

  8. ASP.NET MVC 5 学习教程:Edit方法和Edit视图详解

    原文 ASP.NET MVC 5 学习教程:Edit方法和Edit视图详解 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 ...

  9. ASP.NET MVC 5 学习教程:使用 SQL Server LocalDB

    原文 ASP.NET MVC 5 学习教程:使用 SQL Server LocalDB 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 ...

随机推荐

  1. jQuery json数据处理

    一种是使用jQuery的ajax函数  另一种是使用getJSON函数 使用ajax函数的时候 对于返回值类型dataType 亲自指定为json格式 就无需自己手动处理格式 $.ajax({ url ...

  2. Qt在Linux环境下应用程序字体模糊的解决方法(先改成使用默认字体,然后使用qtconfig配置)

    这两天一直在用Qt实现一个跨平台的软件.软件之前在Windows上编写的,后来放到里Ubuntu 10.10下编译.程序运行时遇到一个很棘手的问题,界面文本非常模糊.后来在网上查阅了好几天的资料,经历 ...

  3. poj 1144 Network(割点)

    题目链接: http://poj.org/problem?id=1144 思路分析:该问题要求求出无向联通图中的割点数目,使用Tarjan算法即可求出无向联通图中的所有的割点,算法复杂度为O(|V| ...

  4. [Django实战] 第8篇 - 分页列表

    当用户登录成功后,首先看到的是他自己之前提交的任务列表,本篇将实现该页面. 视图(views.py)里定义如下: from django.core.paginator import Paginator ...

  5. Android蓝牙开发深入解析

    1. 使用蓝牙的响应权限  代码如下: <uses-permission android:name="android.permission.BLUETOOTH" /> ...

  6. Unity的NGUI插件篇——入场效果

    Unity的NGUI插件篇--入场效果 入场效果 入场效果须要借助于NGUI提供的TweenPosition类来完毕.为了说明此类的用法.本节将使会解说两个演示样例.本文选自  大学霸 <NGU ...

  7. javaweb学习路之三--websocket多人在线聊天

    在之前的项目基础上,加入了一个聊天室的功能,为了界面好看 引入了AmazeUI和umeditor最终效果图如下: 源码在 https://github.com/Zering/MyWeb 目前练习都在这 ...

  8. java异常回顾

    String getMessage():返回此Throwable的详细消息字符串 void PrintStackTrace():将throw及其追踪输出至标准错误流 void printStackTr ...

  9. ARM简介(科普文)

    ARM简介[1] 1. ARM只卖知识产权,不卖(物理的,实质的)产品.    全世界100多家公司购买了ARM授权,包括三星,Freescale.NXP Semiconductors.STMicro ...

  10. BZOJ 1599: [Usaco2008 Oct]笨重的石子( 枚举 )

    直接枚举 ------------------------------------------------------------------------------- #include<cst ...