1. 程式人生 > >net MVC中的模型繫結、驗證以及ModelState

net MVC中的模型繫結、驗證以及ModelState

模型繫結

模型繫結應該很容易理解,就是傳遞過來的資料,建立對應的model並把資料賦予model的屬性,這樣model的欄位就有值了。
比如要建立使用者,在form表單中填寫使用者名稱密碼,在controller中直接使用User類接收就行了:

public ActionResult Create(User user){
     var name=user.Name;
     var pwd=user.Pwd;
     return View();
}

需要注意的是,傳遞每一項資料的名稱和接收的類的屬性名稱必須相同。

模型驗證

經常使用的就是在模型類中給屬性增加特性標籤。如:

    public class HomeFeedbackViewModel
    {
        [Required(ErrorMessage ="尚有未填寫項,請先完善")]
        public string Name { get; set; }
        [Required(ErrorMessage = "尚有未填寫項,請先完善")]
        [EmailAddress(ErrorMessage ="郵箱格式錯誤")]
        public string Email { get; set; }
     } 

這些[Require]、[EmailAddress]之類的就是特性標籤。Require就是說這個屬性不能為空,EmailAddress就是說這個屬性值必須符合一個Email地址格式。這些都是MVC框架封裝好的。

特性都繼承自Attribute,而這些特性標籤都是MVC框架自帶的,繼承自ValidationAttribute(ValidationAttribute繼承自Attribute),如果你自己也想寫一個特性標籤來自定義校驗規則走mvc自帶的校驗流程,記住要繼承ValidationAttribute而不是繼承Attribute。

當請求action時,如果使用模型接收資料,就會自動執行模型繫結,把資料賦予和它相同名稱的屬性欄位,然後校驗屬性的值是否符合屬性上特性標籤的校驗。也可以自己呼叫顯示繫結,詳情見文章
https://blog.csdn.net/litao2/article/details/78568364


如何判斷當前模型是否通過了校驗?
在Controller的 action中經常使用ModelState.IsValid來判斷

        public ActionResult Create(Feedback.ViewModels.HomeFeedbackViewModel Mags)
        {
            if (!ModelState.IsValid)
            {
            return Content('資料校驗不通過');
            }
           return View();
       }

ModelState.IsValid,模型狀態是否有效,很容易理解。我以前一致納悶ModelState從哪裡來的,明明沒有建立它。其實ModelState是System.Web.Mvc.Controller類下的一個成員,因為自己寫的Controller都繼承自System.Web.Mvc.Controller,自然擁有了該名稱空間下的成員,所以可以直接使用。
ModelState是什麼?
這裡寫圖片描述
可以看出他的型別是ModelStateDictionary,翻譯過來是模型狀態字典,也就是很多ModelState的集合。再看下ModelStateDictionary類
這裡寫圖片描述
裡面成員很多,挑幾個說。IsValid是判斷模型驗證是否成功的。Keys我們猜也能猜出來是所有欄位的名稱集合,可以通過Key來訪問ModelState。注意這個ModelState是一個類了和前面的Controller下面的從成員不一樣了,你可以理解為Controller下面的從成員ModelState,就是包含很多ModelState類例項的集合。來看下ModelState
這裡寫圖片描述
Value就是當前欄位的一些資訊比如值、區域資訊之類的。Errors就是當前所驗證屬性上所打的特性標籤驗證失敗的提示資訊,簡單理解就是 [Required(ErrorMessage =”尚有未填寫項,請先完善”)]中的ErrorMessage的集合,比如上面的HomeFeedbackViewModel類中的Email欄位,當輸入Email為空時,既不符合Required的非空要求,也不符合EmailAddress的格式要求,這裡Errors的Count等於2。注意:驗證失敗的錯誤資訊是根據欄位分集合的。

例項:
我們這裡有一個場景,校驗失敗後,返回檢驗失敗的提示。思路就是根據Controller下ModelState這個成員,判斷其屬性IsValid,如果為false,遍歷ModelState的Keys(類的屬性的集合)取出每一個屬性的ModelState,然後判斷屬性的ModelState的成員Errors的數量是否大於0,大於0的話說明這個屬性驗證不通過,返回這一條驗證失敗的錯誤資訊。

           if (!ModelState.IsValid)
            {
                foreach (var key in ModelState.Keys)
                {
                    var modelstate = ModelState[key];
                    if (modelstate.Errors.Any())
                    {
                        return modelstate.Errors.FirstOrDefault().ErrorMessage;
                    }
                }
            }