MVC 中的DataAnnotation Validation attributes[數據註釋驗證屬性] 提供了一種簡單的方法來驗證模型類中的單個屬性值。
那麼CodeFirst是否支持模型對象應用級類上的驗證方法,只管驗證規則而不需要涉及到其他的屬性值?答案是肯定的:只需要在模型類中實現IValidatableObject接口。
下面是一個在Product模型類中使用IValidatableObject[包含在System.ComponentModel.DataAnnotations空間內]接口,實現Validate方法,下面實現兩個驗證規則的實例。
1、如果產品處於斷貨狀態,新產品不能被訂貨。
2、如果庫存超過100unit,那麼新產品不能被訂購。
下面就來實現上述驗證規則
第一步:定義產品模型類並繼承IValidatableObject接口,實現其方法Validate
public class Product:IValidatableObject { public int ProductID { get; set; } public int CategoryID { get; set; } public string ProductName { get; set; } public Decimal? UnitPrice { get; set; } public Int16? UnitsInStock { get; set; } public Int16? UnitsOnOrder { get; set; } public bool Discontinued { get; set; } /// <summary> /// 驗證多個業務邏輯 /// </summary> /// <param name="validateContext"></param> /// <returns></returns> public IEnumerable<ValidationResult> Validate(ValidationContext validateContext) { if ((UnitsOnOrder > 0) && (Discontinued)) //這裏注意 yield 關鍵字向編譯器指示它所在的方法是迭代器 yield return new ValidationResult("Can't order discontinued products!", new[] { "UnitsOnOrder" }); //指定UnitsOnOrder 屬性的錯誤 描述 if ((UnitsInStock > 100) && (UnitsOnOrder > 0)) yield return new ValidationResult("We already have a lot of these!", new[] { "UnitsInStock" }); } }
第二步:創建ProductController,然後建立名爲Create 的ActionResult方法
第一個Create()方法實現一種/Product/Create URL來處理HTTP-GET請求,並顯示HTML表單以供填寫。第二個Create()方法實現另一種/Product/Create URL來處理HTTP-Post請求——它取出提交的表單數據,保證它的有效性,如果有效的話將其保存在數據庫內。 如果驗證有問題,它會重新顯示錶單和它提交的值。
public class ProductController : Controller { DbContexts context = new DbContexts(); // // GET: /Product/ public ActionResult Create() { return View(); } [HttpPost] public ActionResult Create(Product product) { if (!ModelState.IsValid) { context.products.Add(product); //product.UnitsOnOrder = 5; //product.Discontinued = true; var errors = context.GetValidationErrors(); if (errors.Count() > 0) { return View(product); } context.SaveChanges(); } return View(product); } }
第三步:生成View
@model ClassLevelModelValidate.Models.Product @{ ViewBag.Title = "Create"; } <h2>Create</h2> <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>Product</legend> <div class="editor-label"> @Html.LabelFor(model => model.CategoryID) </div> <div class="editor-field"> @Html.EditorFor(model => model.CategoryID) @Html.ValidationMessageFor(model => model.CategoryID) </div> <div class="editor-label"> @Html.LabelFor(model => model.ProductName) </div> <div class="editor-field"> @Html.EditorFor(model => model.ProductName) @Html.ValidationMessageFor(model => model.ProductName) </div> <div class="editor-label"> @Html.LabelFor(model => model.UnitPrice) </div> <div class="editor-field"> @Html.EditorFor(model => model.UnitPrice) @Html.ValidationMessageFor(model => model.UnitPrice) </div> <div class="editor-label"> @Html.LabelFor(model => model.UnitsInStock) </div> <div class="editor-field"> @Html.EditorFor(model => model.UnitsInStock) @Html.ValidationMessageFor(model => model.UnitsInStock) </div> <div class="editor-label"> @Html.LabelFor(model => model.UnitsOnOrder) </div> <div class="editor-field"> @Html.EditorFor(model => model.UnitsOnOrder) @Html.ValidationMessageFor(model => model.UnitsOnOrder) </div> <div class="editor-label"> @Html.LabelFor(model => model.Discontinued) </div> <div class="editor-field"> @Html.EditorFor(model => model.Discontinued) @Html.ValidationMessageFor(model => model.Discontinued) </div> <p> <input type="submit" value="Create" /> </p> </fieldset> } <div> @Html.ActionLink("Back to List", "Index") </div>
下圖是違反了業務邏輯規則的截圖