EF Code First和MVC3進行類級別模型驗證

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

View Code
@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>

下圖是違反了業務邏輯規則的截圖

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章