[.NET MVC4 入门系列07] 在Model模型模块中添加验证
【本章目标】
为Movie Model 添加验证,当Movie创建或更改时,能够起到作用。
【Keeping Things DRY】
指的还是MVC中的代码重用逻辑,这里将其总结为" Don't Repeat Yourself ",简称DRY
验证规则添加到Model模块的类中,但是可以在项目的任意位置调用。
【操作步骤】
一、向Movie Model中添加验证规则:
1.向Movie类(\Models\Movies.cs)中添加验证逻辑
首先,添加命名空间:using System.ComponentModel.DataAnnotations;
该命名空间的作用是,支持built-in set of validation attribute (内置整套验证特性修饰符)
然后,更新Movies.cs代码:
1 public class Movie 2 { 3 public int ID { get; set; } 4 5 [Required] 6 public string Title { get; set; } 7 8 [DataType(DataType.Date)] 9 public DateTime ReleaseDate { get; set; } 10 11 [Required] 12 public string Genre { get; set; } 13 14 [Range(1,100)] 15 [DataType(DataType.Currency)] 16 public decimal Price { get; set; } 17 18 [StringLength(5)] 19 public string Rating { get; set; } 20 }
[代码解析]:
在后五个property前加的[。。。]成为“验证特性(Validation Attribute)”.
[Required]:限定当前属性不能为空,必须非null;
[DataType(DataType.XXX)]:限定当前属性只接收指定类型的数据;
[Range(1,100)]:限定属性取值范围;
[StringLength(5)]:限定属性字符串最大长度;
还有很多,一般都很简单,直接都能看出其意义,如果要查资料的话,来这里:
http://msdn.microsoft.com/en-us/library/ee256141%28v=VS.100%29.aspx
下面这个链接还是本文第一个:System.ComponentModel.DataAnnotations命名空间的MSDN链接
http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations(v=vs.100).aspx
其中,Classes里大多数后缀名为"Attribute"的都可以当做Validation Attribue放在所修饰的property之前,作为验证逻辑来使用。具体每个Attribute的使用方法,可以单独点入这个Attribute类的MSDN介绍来详细查看。
例如:
FileExtensionsAttribute 类对应的Valaditon Attribute 用法如下,
[FileExtensions(Extensions =
"jpg,jpeg"
)]
上面的代码很明显是限定后缀名的,非常方便.
2.更新数据库
现在重新运行程序,会出现如下错误:
因为项目使用的是Entity Framework, 所以每次Model中的Movie类被更改后,都需要更新数据库。
打开"程序包管理控制台",输入如下命令来更新数据库,并执行:
1)第一条命令:add-migration AddDataAnnotationsMig 指定更改数据库的规则
执行后,会在\Migrations 中生成一个新的以AddDataAnnotationsMig为后缀的DbMigration类,来处理数据库的更新逻辑(up方法对应数据库的update);
2)第二条命令:update-database 执行具体的更改操作。
3.运行程序,得到如下效果:
可以看到,验证已经加入系统.并且,MVC4中的验证是同时加入客户端和服务器端的.和以前ASPX页中的验证控件一样,除非先通过客户端验证,否则是不能进入服务器端的.
【验证原理】
1.查看MovieController类中的Edit和Create方法
1 // GET: /Movies/Create 2 3 public ActionResult Create() 4 { 5 return View(); 6 } 7 8 // 9 // POST: /Movies/Create 10 11 [HttpPost] 12 [ValidateAntiForgeryToken] 13 public ActionResult Create(Movie movie) 14 { 15 if (ModelState.IsValid) 16 { 17 db.Movies.Add(movie); 18 db.SaveChanges(); 19 return RedirectToAction("Index"); 20 } 21 22 return View(movie); 23 } 24 25 // 26 // GET: /Movies/Edit/5 27 28 public ActionResult Edit(int id = 0) 29 { 30 Movie movie = db.Movies.Find(id); 31 if (movie == null) 32 { 33 return HttpNotFound(); 34 } 35 return View(movie); 36 } 37 38 // 39 // POST: /Movies/Edit/5 40 41 [HttpPost] 42 [ValidateAntiForgeryToken] 43 public ActionResult Edit(Movie movie) 44 { 45 if (ModelState.IsValid) 46 { 47 db.Entry(movie).State = EntityState.Modified; 48 db.SaveChanges(); 49 return RedirectToAction("Index"); 50 } 51 return View(movie); 52 }
查看代码,发现每种操作都对应两个方法重载,其中前面第一个没有特性前缀是HTTP GET模式访问服务器的,而第二个带有[HttpPost] attribute的方法是使用HTTP POST方式向服务器提交数据的。
第一个GET方法用来显示初始化的界面,并处理客户端验证;这时如果用户数据有误,就根本不会进入第二个POST方法。
如果JS被浏览器禁用,第一个GET方法只用来显示初始化界面,客户端验证失效,才会进入第二个Post方法,使用服务器端验证:
if (ModelState.IsValid)
只有当服务器端验证通过后,才会进行数据库更新:
db.SaveChanges();
2.看完后台代码,再来看前台View
打开Create.cshtml
1 <fieldset> 2 <legend>Movie</legend> 3 4 <div class="editor-label"> 5 @Html.LabelFor(model => model.Title) 6 </div> 7 <div class="editor-field"> 8 @Html.EditorFor(model => model.Title) 9 @Html.ValidationMessageFor(model => model.Title) 10 </div> 11 12 <div class="editor-label"> 13 @Html.LabelFor(model => model.ReleaseDate) 14 </div> 15 <div class="editor-field"> 16 @Html.EditorFor(model => model.ReleaseDate) 17 @Html.ValidationMessageFor(model => model.ReleaseDate) 18 </div> 19 20 <div class="editor-label"> 21 @Html.LabelFor(model => model.Genre) 22 </div> 23 <div class="editor-field"> 24 @Html.EditorFor(model => model.Genre) 25 @Html.ValidationMessageFor(model => model.Genre) 26 </div> 27 28 <div class="editor-label"> 29 @Html.LabelFor(model => model.Price) 30 </div> 31 <div class="editor-field"> 32 @Html.EditorFor(model => model.Price) 33 @Html.ValidationMessageFor(model => model.Price) 34 </div> 35 36 <div class="editor-label"> 37 @Html.LabelFor(model=>model.Rating) 38 </div> 39 40 <div class="editor-field"> 41 @Html.EditorFor(model=>model.Rating) 42 @Html.ValidationMessageFor(model=>model.Rating) 43 </div> 44 <p> 45 <input type="submit" value="Create" /> 46 </p> 47 </fieldset>
黄色高亮的就是验证信息显示代码.
使用的是@Html.ValidationMessageFor(对象=>对象.Property),它和前面的输入input控件相绑定,用来验证input中输入的数据。
实际上,有趣的是,Create 的 Controller和 View 都不知道验证规,也不知道如何显示错误信息。验证逻辑和错误信息我们从前面可以了解到,是由Movie类property的Validation Attribute设定的。
和以前的验证控件相比,这种方式将验证和显示相剥离,验证逻辑的重用性有了大幅度提升.
【总结】
在Asp.net的官方网站上,这个系列还有最后一篇文章,来说明Details和Delete方法,比较简单,在此就不再介绍。
这个系列就到此结束,我正在整理的是另一个更完整的介绍MVC 4的系列。用的是Pro MVC 4那本书。
会按照章节详细介绍.坑可能有点大,估计至少要3个月才能弄完.
MVC 4弄完后,会再介绍Web API,和.NET 多端程序类架构,争取在这13年一年内,把.NET新技术的基本用法过一遍。
初学MS 的MVC 4,参照微软www.asp.net/mvc 中的入门项目,写个MVC 4的入门系列,以供复习和分享。
微软入门项目:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/intro-to-aspnet-mvc-4
【目录】
1.[.NET MVC4 入门系列01]Helloworld MVC 4 第一个MVC4程序
2. [.NET MVC4 入门系列02]MVC Movie 为项目添加Model
3. [.NET MVC4 入门系列03]使用Controller访问Model中数据
4. [.NET MVC4 入门系列04]Controller和View间交互原理
5. .NET MVC4 入门系列05]添加自定义查询页Search
6. [.NET MVC4 入门系列06] 在Movie Model和表中添加新字段(Code First Migrations)
7. [.NET MVC4 入门系列07] 在Model模型模块中添加验证