本節你將為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">)。您可以使用Regex來驗證格式化資料。
使用的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.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/accessing-your-models-data-from-a-controller
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/05/2803429.html
6. 查看Edit方法和Edit視圖
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/examining-the-edit-methods-and-edit-view
· 譯文地址: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.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-new-field-to-the-movie-model-and-table
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/06/2805401.html
8. 為模型添加驗證
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-validation-to-the-model
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/06/2806322.html
9. 查看Detail和Delete方法
· 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/examining-the-details-and-delete-methods
· 譯文地址:http://www.cnblogs.com/seawaving/archive/2012/12/10/2811064.html