本節你將為Movie類型增加邏輯驗證,以確保任何用戶試圖使用該應用程序創建或編輯影片時執行驗證規則。
DRY(干爽)
ASP.NET MVC的核心原則之一是干爽(“不要自己重復”)。ASP.NET MVC鼓勵您只指定一次功能或行為,然后在應用程序中到處使用。這種做法減少了需要編寫的代碼量,使你的代碼編寫不容易出錯,且更容易維護。
ASP.NET MVC和Entity Framework代碼先行為驗證提供支持,是干爽原則應用的一個很好的例子。在一個模型的類中以聲明方式指定驗證規則,在整個應用程序中執行驗證規則。
讓我們來看看如何在電影應用程序中利用驗證支持。
向Movie模型中添加驗證規則
首先向Movie類中加入一些驗證邏輯。
打開的Movie.cs文件。在文件的頂部添加using語句,引用命名空間:using System.ComponentModel.DataAnnotations;
請注意,命名空間中不包含的System.Web。 DataAnnotations提供了內置的驗證屬性,你可以對任何類或屬性應用。
現在修改Movie類,利用內置的Required、StringLength,和Range驗證屬性。下面的代碼是應用屬性的例子:
public class Movie { public int ID { get; set; } [Required] public string Name { get; set; } public string Genra { get; set; } [Range(1,100)] public decimal Price { get; set; } public DateTime Date { get; set; } [StringLength(5)] public string Rating { get; set; } }
運行程序后你會再次遇到錯誤:
支持“MovieDbContext”上下文的模型已在數據庫創建后發生更改。請考慮使用 Code First 遷移更新數據庫(http://go.microsoft.com/fwlink/?LinkId=238269)。
按上節學習的步驟,先在庫管理器控制台中執行add-migration AddDataAnnotationsMig命令,再執行update-database命令,查看AddDataAnnotationsMig文件,其中的Up方法,可以看到Name字段不能為空,Rating屬性最大長度為5。
public override void Up() { AlterColumn("dbo.Movies", "Name", c => c.String(nullable: false)); AlterColumn("dbo.Movies", "Rating", c => c.String(maxLength: 5)); }
驗證屬性指定應用到模型屬性要執行的行為。Required屬性表示屬性不能為空,在本示例中,影片名稱必須有值。Range范圍屬性限制值在指定的范圍內。 StringLength屬性可讓您設定字符串最大長度,以及最小長度(可選)。內建類型(如decimal, int, float, DateTime)默認情況下,並不需要Required屬性。
代碼先行確保應用程序將更改保存到數據庫前你指定的模型類的驗證規則被執行。例如,下面的代碼調用SaveChanges方法時將拋出一個異常,因為不能為空的的片名屬性值沒有值,以及價格是零(不在有效范圍內)。
MovieDbContext db = new MovieDbContext(); Movie movie = new Movie(); movie.Title = ""; movie.Price = 0.0M; db.Movies.Add(movie); db.SaveChanges();
.NET Framework自動執行驗證規則,使您的應用程序更加健壯。它可確保您不忘記驗證東西,以及不經意間讓錯誤的數據存到數據庫中。
ASP.NET MVC中驗證出錯界面
運行程序,點擊“新建”鏈接,新建一部影片。使用一些無效數據來填充表單,然后點擊創建按鈕。

請注意,表單自動使用紅色邊框的突出顯示包含無效的數據的文本框,並在每一個旁邊提示適當的驗證錯誤消息。錯誤包括客戶端(使用JavaScript和jQuery)和服務器端(如果用戶已禁用JavaScript)。
一個真正的好處是,你並不需要改變MoviesController類或者 Create.cshtml視圖中的一行代碼,就可以實現驗證界面。您在本教程前面創建的控制器和視圖,自動使用您指定的Movie模型類的屬性上的驗證屬性的驗證規則。
您可能已經注意到的Name屬性,Required屬性沒有被執行,直到您提交表單(點擊Create按鈕),或在輸入字段中輸入文本並刪除它。初始值為空(如創建視圖中的字段)且只有required屬性,沒有其他的驗證屬性的字段,你可以執行以下操作來觸發驗證:
1.Tab鍵進入該字段。
2.輸入一些文字。
3.Tab鍵移出。
4.按Tab切換回進入該字段。
5.刪除文本。
6.Tab鍵移出。
上述順序將觸發所要求的驗證,不需要點擊“提交”按鈕。只要按“提交”按鈕,無需進入任何字段,將觸發客戶端驗證。若沒有客戶端驗證錯誤,則表單數據發送到服務器。您可以通過在HTTP POST方法設置斷點或者使用Fiddler工具或IE 9 F12開發人員工具來測試這點。
創建視圖和創建方法中如何觸發驗證
你可能想知道生成的控制器或視圖中的代碼沒有任何更新的情況下驗證界面是如何產生的。下一個清單顯示的是在MovieController類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); }
第一個(HTTP GET)Create的操作方法顯示初始創建表單。第二個([HttpPost])版本的操作方法負責處理post請求。第二個Create的方法(HttpPost版本)調用ModelState.IsValid,以檢查是否有任何驗證錯誤。調用該方法將檢查任何已應用到對象屬性上的驗證。如果對象的Create方法驗證錯誤,重新顯示表單。如果沒有錯誤,該方法在數據庫中保存新的電影。在我們的電影例子中,在客戶端驗證檢測到的錯誤,表單將不會發送到服務器時,第二個Create方法不會被調用。如果您在您的瀏覽器禁用了JavaScript,客戶端驗證被禁用,HTTP POST版本的Create方法調用ModelState.IsValid,以檢查是否有任何驗證錯誤。
您可以在HttpPost Create方法中設置一個斷點,驗證該方法不會被調用,客戶端驗證發現錯誤時將不提交表單數據。如果您在您的瀏覽器禁用了JavaScript,然后提交有錯誤的表單,斷點會命中。不支持JavaScript的情況下,你仍然可以得到充分驗證。
請注意,代碼是如何使用Html.EditorFor助手為每個Movie屬性輸出<input>元素的。也注意下 Html.ValidationMessageFor助手。這兩個輔助方法,通過控制器傳遞給視圖的模型對象(在本例中是Movie對象)發生作用。它們自動尋找模型上指定的驗證屬性並顯示驗證錯誤信息。
控制器和Create視圖模板不知道什么實際的驗證規則正在執行或特定的錯誤消息顯示,這種做法非常好。只需要在Movie類里指定驗證規則和錯誤字符串,同樣的驗證規則會自動應用到編輯視圖和任何其他視圖模板,您可以創建,編輯您的模型。
如果你想更改的驗證邏輯,你可以限定在一處地方(在這個例子中,Movie類),為模型添加驗證屬性。你不需要擔心應用程序的不同部分執行的規則不一致- 所有的驗證邏輯將被定義在一個地方,應用在各個地方。這樣可以使代碼很干凈,而且很容易進行維護和改進。這意味着,你會充分履行了DRY原則。
為模型添加格式化信息
打開的Movie.cs的文件,查看的Movie類。 System.ComponentModel.DataAnnotations命名空間中除了內置的驗證屬性,還提供了格式化屬性。下面的代碼顯示了添加適當的DisplayFormat屬性的Date和Price。
[DataType(DataType.Currency)] public decimal Price { get; set; } [DataType(DataType.Date)] public DateTime Date { get; set; }
DataType屬性不是驗證屬性,它是用來告訴視圖引擎如何生成HTML。在上面的例子中,DataType.Date屬性顯示Date為日期,不包含時間。例如,下面的數據類型屬性不驗證數據格式:
[DataType(DataType.EmailAddress)]
[DataType(DataType.PhoneNumber)]
[DataType(DataType.Url)]
上面列出的屬性為視圖引擎格式化數據提供一些參考(為url提供<a>以及為email提供<a href="mailto:EmailAddress.com">)。您可以使用正則表達式來驗證格式化數據。
使用的DataType屬性的另一種方法,你可以顯式設置DataFormatString值。下面的代碼顯示的日期格式字符串(即“D”)的發布日期屬性。使用該功能,表明你不想把時間作為日期的一部分。
[DisplayFormat(DataFormatString = "{0:d}")]
public DateTime ReleaseDate { get; set; }
下面的代碼將Price屬性格式化為貨幣
[DisplayFormat(DataFormatString = "{0:c}")]
public decimal Price { get; set; }
在下節課程中,我們將回顧應用程序,為自動生成的Details和Delete方法做出一些改進。
本教程所有文章導航
本系列共10篇文章,翻譯自Asp.Net MVC4 官方教程,由於本系列文章言簡意賅,篇幅適中,從一個示例開始講解,全文最終完成了一個管理影片的小系統,非常適合新手入門Asp.Net MVC4,並由此開始開發工作。
原文供9篇文章,譯者將其中第6篇拆成了2篇
1. Asp.Net MVC4 入門介紹
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/intro-to-aspnet-mvc-4
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/03/2800210.html
2. 添加一個控制器
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-controller
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/04/2801949.html
3. 添加一個視圖
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-view
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/04/2801988.html
4. 添加一個模型
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-model
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/05/2803012.html
5. 從控制器訪問數據模型
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/05/2803429.html
6. 查看Edit方法和Edit視圖
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/05/2804100.html
http://www.cnblogs.com/seawaving/archive/2012/12/06/2804590.html
7. 為Movie模型和庫表添加字段
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/06/2805401.html
8. 為模型添加驗證
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/06/2806322.html
9. 查看Detail和Delete方法
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/10/2811064.html
