ASP.NET MVC5----常見的數據註解和驗證

  只要一直走,慢點又何妨。javascript

在使用MVC模式進行開發時,數據註解是常用的(模型之上操做),下面是我看書整理的一些常見的用法。html

什麼是驗證,數據註解

驗證java

從全局來看,發現邏輯僅是整個驗證的很小的一部分。驗證首先須要管理用戶友好(本地化)的與驗證邏輯相關的錯誤提示消息;當驗證失敗時,在把這些錯誤提示消息呈現給用戶界面上,固然還要向用戶提供從驗證失敗中恢復的機制。正則表達式

數據註解sql

註解是一種通用機制,能夠用來向框架注入元數據,同時,框架不僅驅動元數據的驗證,還能夠在生成顯示和編輯模型的HTML標記時使用元數據。通俗的說就是模型上面的特定標識符(具備必定意義和做用)。數據庫

驗證註解的使用

數據註解定義在通常在命名空間」System.ComponentModel.DataAnnotations」提供了服務器端驗證的功能,在模型屬性上使用時,框架也支持客戶端驗證。註解後面都是能夠添加錯誤提示語的,ErrorMessage是每一個驗證特性中用來設置錯誤提示消息的參數,好比:編程

        [Required(ErrorMessage = "不能爲空")]
        public int Age { get; set; }
  • Required

強調屬性是必須的,不可爲空。當屬性中有一個是null或空時,會引起一個驗證錯誤。json

        [Required]
        public int Age { get; set; }
  • StringLength

要求必須輸入名字的長度。參數能夠限制最小的。以下:數組

        [StringLength(160,MinimumLength = 3)]
        public string Name { get; set; }
  • RegularExpression

正則表達式驗證,好比郵箱等須要驗證正則的地方。非常方便,這樣就減小了服務端的驗證。安全

        [RegularExpression(@"^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+",ErrorMessage = "郵箱輸入有誤,從新輸入。")]        
        public string Email { get; set; }
  • Range

用來指定數值類型值得最小值和最大值。主要爲int類型服務。其他的也能夠,須要使用構造函數的重載版本。Type參數來作。

       [Range(20,30,ErrorMessage = "年齡不符合要求")]
        public int Age { get; set; }

        [Range(typeof(decimal),"0.00","59.99")]
        public decimal Price { get; set; }

  • Compare

肯定兩個模型屬性擁有同樣的值。密碼的驗證(輸入兩次,看兩者是否同樣。),參數爲前面模型的值。

        [Required(ErrorMessage = "密碼不能爲空")]
        public string Password { get; set; }
        [Compare("Password")]
        public string PasswordPalt { get; set; }
  • Remote

此特性利用服務器端的回調函數執行客戶端的驗證邏輯。通俗的說就是這個特性能夠直接找到某個控制器的action而且執行其中的方法。

image


        /// <summary>
        /// 驗證模型中輸入的姓名是否和數據庫中重複
        /// </summary>
        /// <returns></returns>
        public JsonResult CheckUserName(string username)
        {
            //數據庫中的相關驗證
            return Json(DateTime.Now.ToString(),JsonRequestBehavior.AllowGet);
        }

        [Remote("CheckUserName", "Admin")]
        public string UserName { get; set; }

上面控制器操做會利用與UserName屬性同名的參數進行驗證,同時返回一個javascript object Notaion(json)對象中的布爾類型值(0/1)

  • 自定義回覆消息佔位符

使用{0}佔位符,來顯示用戶的輸入,而且造成友好提示。

        [Range(20,30,ErrorMessage = "年齡{0}不符合要求")]
        public int Age { get; set; }

服務端的一些處理(驗證與綁定)

ASP.NET MVC的驗證特性是由模型綁定器,模型元數據,模型驗證器和模型狀態組成。

驗證和模型綁定

  • 操做方法中添加參數

這裏有一個隱式地執行模型綁定,通常咱們都須要這樣寫,這樣也安全,不會說暴露出來參數。

  • 利用UpdateModel或TryUpdateModel方法顯式執行綁定

這個實際項目中使用的不多,通常都是經過隱式進行轉換的。


        [HttpPost,ActionName("Create")]
        public ActionResult CreatePost(Student model)
        {
            var model2 = new Student();
            UpdateModel(model2);
            if (TryUpdateModel(model2))
            {
                 
            }
            return View(model);
        }

 


能夠看到參數中的爲隱式轉換,裏面的model2爲顯式轉換。if中的返回的是bool類型。模型綁定器一旦使用新值完成對模型屬性的更新,就會利用當前的 模型元數據得到模型的全部驗證器。MVC運行時提供了一個驗證器(DataAnnotationsModelValidator)來與數據註解一同工做,這個模型驗證器會找到全部的驗證特性並執行它們包含的驗證邏輯,模型綁定器捕獲全部失敗的驗證規則並把它們放入模型狀態中

   編程的一個重要原則是不能相信用戶的輸入

驗證與模型狀態

模型綁定的副產品是模型狀態,也就是咱們服務端驗證的ModelState,此狀態中不只包含用戶的輸入,也含有每一個相關屬性的全部錯誤(與模型狀態自己有關的錯誤),有錯誤,ModelState.IsValid就返回false。從而咱們就能夠進行驗證。

        public ActionResult CreatePost(Student model)
        {
            var s=ModelState.IsValidField("UserName");
             var ss=ModelState["UserName"].Errors.Count;
            var userName = ModelState["UserName"].Errors[0].ErrorMessage;  //獲取錯誤消息
            if (ModelState.IsValid)      //返回bool類型
            {                 
            }
            return View(model);
        }

顯示和編輯註解

  • Display

顯示模型屬性設置友好的「顯示名稱」

        [Display(Name = "姓名")]
        [StringLength(160,MinimumLength = 3)]
        public string Name { get; set; }
  • ScaffoldColumn

能夠隱藏HTML的輔助方法

image

        [ScaffoldColumn(false)]
        public string Address { get; set; }
  • DisplayFormat

處理屬性各類格式化選項,當屬性包含空值,能夠提供可選的顯示文本。也能夠爲包含標記的屬性關閉HTML編碼。還能夠運行時指定一個應用於屬性值的格式化字符串。

        [DisplayFormat(ApplyFormatInEditMode = true,DataFormatString = "{0:c}")]
        public decimal Total { get; set; }
  • ReadOnly

能夠確保默認的模型綁定器不使用請求中的新值來更新屬性。

  • DataType

運行時提供關於屬性的特定用途信息。String類型的屬性可應用於不少場合--能夠保存e-mail地址,URL或密碼。

        [Required(ErrorMessage = "密碼不能爲空")]
        [DataType(DataType.Password)]
        public string Password { get; set; }

  • UIHint

給運行時提供一個模版名稱,以備調用模版輔助方法渲染輸出時使用。

自定義驗證邏輯

  1. 將驗證邏輯封裝在自定義的數據註解中。
  2. 將驗證邏輯封裝在模型對象中。

把驗證邏輯封裝在自定義的數據註解中能夠輕鬆地實如今多個模型中重用邏輯。須要在特性內部編寫代碼以應對不一樣類型的模型中。

自定義註解

全部的驗證註解特性最終都派生自基類ValidationAttribute,它是個抽象類,在System.ComponentMode.DataAnnotation中定義。一樣自定義的驗證邏輯必須派生自ValidationAttribute的類。且重寫IsValid方法(方法裏面實現咱們相應的邏輯)。

需求:限制用戶輸入地址中單詞數量,設定一個最大值。

    /// <summary>
    /// 自定義模型驗證
    /// 輸入數字的單詞最大數量
    /// </summary>
    public class MaxWordsAttribute:ValidationAttribute
    {
        private readonly int _maxWord;
        public MaxWordsAttribute(int maxWord)
        {
            _maxWord = maxWord;
        }
        protected override ValidationResult IsValid(object value,ValidationContext validationContext)
        {
            if (value!=null)
            {
                //將輸入轉換爲string類型
                var valueAsString = value.ToString();
                //使用split(' ')空格來分隔輸入值,統計生成字符串的數量。對數目比較驗證。
                if (valueAsString.Split(' ').Length>_maxWord)      
                {
                     return new ValidationResult("單詞超過長度");  //string類型
                }
            }
            return ValidationResult.Success;         //bool類型
        }
    }

第一個參數要驗證對象中的值。後面進行邏輯的判斷。這樣作這裏的錯誤提示不能顯示到前臺。咱們須要修改下,使用ValidationAttrubute的ErrorMessage屬性來自定義提示錯誤消息。

修改以後


    public class MaxWordsAttribute:ValidationAttribute
    {
        private readonly int _maxWord;
        public MaxWordsAttribute(int maxWord)
            :base("{0} has too many words")     
        {
            _maxWord = maxWord;
        }
        protected override ValidationResult IsValid(object value,ValidationContext validationContext)
        {
            if (value!=null)
            {
                //將輸入轉換爲string類型
                var valueAsString = value.ToString();
                //使用split(' ')空格來分隔輸入值,統計生成字符串的數量。對數目比較驗證。                
                if (valueAsString.Split(' ').Length>_maxWord)
                {
                    var errorMessage = FormatErrorMessage(validationContext.DisplayName);
                     return new ValidationResult(errorMessage);  
                }
            }
            return ValidationResult.Success;         //bool類型
        }
    }

        [MaxWords(5)]        
        public string Address { get; set; }

這樣效果就會將咱們基類中的錯誤信息顯示出來。

image

咱們能夠模型基礎上添加自定義錯誤顯示。

        [MaxWords(5,ErrorMessage = "你輸入的單詞數超界限,請從新輸入。")]        
        public string Address { get; set; }

image

這裏須要注意這裏的執行順序,它是先執行模型上面的驗證,接着在到控制器中的action中去的。利用ModelState.IsValid來進行驗證。

自驗證模型(IValidatableObject)

自驗證模型是指一個知道如何驗證自身的模型對象,可讓類實現IVaalidatableObject接口來實現對自身的驗證。

    public class Information:IValidatableObject
    {
        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if (UserName!=null&&UserName.Split(' ').Length>5)
            {
                 yield return new ValidationResult("單詞超界限了");
            }             
        }
        [Display(Name = "用戶名")]
        public string UserName { get; set; }        
    }

image


其實書上面是在錯誤返回值中返回的是string類型的數組,以下

yield return new ValidationResult("單詞超界限了",new []{"UserName"});

能夠我不知道從那裏取出來這個錯誤消息。只能單獨的顯示出來。其實把錯誤消息放在數組中能夠進行多模型的驗證,從而統一將錯誤顯示出來。

本身的感受要是須要模型驗證,最好仍是進行第一種方法,最起碼代碼看起來乾淨,第二種給人的感受是很亂,可是第二種適合比較模型多的場合。

   我就是我,顏色不同的煙火。

相關文章
相關標籤/搜索