您的位置:首页 > 其它

[.NET MVC4 入门系列07] 在Model模型模块中添加验证

2017-03-15 15:51 477 查看
对应文章:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-validation-to-the-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 HttpNot
fabc
Found();
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新技术的基本用法过一遍。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: