【本章目標】
為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模型模塊中添加驗證