第十節:數據批註(DataAnnotationModel)和自定義驗證(包括Model級別的驗證)

一. 簡介html

  寫完上一個章節MVC中的經常使用特性,火燒眉毛將該系列補全,該章節主要介紹數據批註(也叫:註解)。前端

  一聽【數據批註】,好高大上的名字,但仔細一看,它們實際上是【System.ComponentModel.DataAnnotations】程序集下的一些特性類,O(∩_∩)O哈哈~,既然是特性,就符合特性的全部特徵,只不過這些特性是做用於「屬性」上的。ajax

  再一看【System.ComponentModel.DataAnnotations】這個命名空間,有點眼熟,與以前EF中的一篇文章【EF的CodeFirst模式經過DataAnnotations修改默認協定】中的一類操做來源於同一個命名空間下。數據庫

  因此綜上所述:該命名空間下的特性,在EF中能夠用來映射生成數據庫中的表字段,在平常開發中也能夠用於作類中屬性的限制和驗證。安全

原理:均繼承了ValidationAttribute特性,經過覆寫IsValide方法進行校驗。服務器

適用場景:不少項目須要客戶端和服務器端進行雙重格式驗證,使之更加安全,這時服務器端就可使用數據批註了來進行校驗了。併發

以Required特性爲例,查看一下源碼:框架

 

二. 經常使用的數據批註ide

這裏總結一下【System.ComponentModel.DataAnnotations】命名空間下經常使用的數據批註,即特性。測試

 ① Key :聲明主鍵

 ② Required:非空聲明

 ③ MinLength和MaxLength:設置string類型的最大長度和最小長度,數據庫的對應nvarchar

 ④ StringLength:設置string類型的長度,數據庫對應nvarchar

 ⑤ Compare:新老密碼對比

 ⑥ RegularExpression:正則的匹配

 ⑦ Phone:驗證手機號碼

 ⑧ Range:驗證範圍

 ⑨ Timestamp:將byte[]類型設置爲timestamp類型  

 ⑩ ConcurrencyCheck:併發檢查,執行update操做時,會檢查併發性(樂觀鎖)   (在後面併發章節着重介紹Timestamp和ConcurrencyCheck)

另外還有一些不是很經常使用的,如:

 ① DisplayName:聲明屬性的名稱

 ② Remote:遠程驗證,須要JQuery插件的支持  (這裏不作測試等待補充  參考: https://www.cnblogs.com/JustRun1983/p/3505151.html)

 下面補充一下該命名空間反射源碼,能夠自行查找須要的批註:

 

代碼測試: 

(1). 實體類,在其屬性上添加數據標註

 1     /// <summary>
 2     /// 用戶信息類 ,用於測試框架自己提供的數據批註
 3     /// </summary>
 4     public class UserInfor
 5     {
 6         [Required]
 7         public string id { get; set; }
 8 
 9         [StringLength(4)]
10         public string userName { get; set; }
11 
12         [MaxLength(8)]
13         public string userMsg { get; set; }
14 
15         [Range(2, 10)]
16         public int userAge { get; set; }
17 
18         [RegularExpression("[a-d]")]   //a-d中的一個
19         public string userMsg3 { get; set; }
20 
21         [Phone]
22         public string userPhone { get; set; }
23 
24         public string userOldPwd { get; set; }
25 
26         [Compare("userOldPwd")]  //比較和userOldPwd的值是否相等
27         public string userNewPwd { get; set; }
28 
29     }
View Code

(2). 前端代碼

 1            //1. 測試數據批註
 2             $("#btn1").click(function () {
 3                 $.ajax({
 4                     type: "Post",  
 5                     url: "TestDataAnnotationModel",
 6                     data: {
 7                         "id":"123",
 8                         "userName": "mr12",
 9                         "userMsg": "ypf1234",
10                         "userAge": 6,
11                         "userMsg3": "a",
12                         "userPhone": "15764222366",
13                         "userOldPwd": "123456",
14                         "userNewPwd":"123456"
15 
16                     },
17                     success: function (data) {
18                         if (data == "ok") {
19                             alert("測試經過");
20                         }
21                         if (data == "error") {
22                             alert("測試未經過");
23                         }
24                     }
25                 });
26             });        
View Code

(3). 服務器端代碼

 1   public ActionResult TestDataAnnotationModel(UserInfor user)
 2         {
 3             //經過該方法進行驗證
 4             var isValidate = ModelState.IsValid;
 5 
 6             if (isValidate)
 7             {
 8                 return Content("ok");
 9             }
10             return Content("error");
11         }
View Code

 

三. 自定義數據批註

 思路:經過上面的批註源碼可知,均爲自定義類繼承:ValidationAttribute,覆寫IsValid方法

 需求:這裏咱們自定義一個批註,要求不爲空,且長度區間爲6-12位

 使用方法一樣爲:action中經過實體接收,經過ModelState.IsValid的值爲true或false來判斷驗證是否經過

代碼測試:

(1). 實體類和自定義批註

 1     /// <summary>
 2     /// 角色類,用於測試自定義業務的數據批註
 3     /// </summary>
 4     public class RoleInfor
 5     {
 6 
 7         public string id { get; set; }
 8 
 9         [myOwnCheck]
10         public string roleName { get; set; }
11     }
12 
13     /// <summary>
14     /// 自定義數據批註,要求非空且長度爲6-12位
15     /// </summary>
16     public class myOwnCheckAttribute : ValidationAttribute
17     {
18         public override bool IsValid(object value)
19         {
20             if (value != null && value.ToString().Length > 6 && value.ToString().Length < 12)
21             {
22                 return true;
23             }
24             return false;
25         }
26     }
View Code

(2). 前端代碼

 1            //2. 測試自定義業務邏輯的驗證
 2             $("#btn2").click(function () {
 3                 $.ajax({
 4                     type: "Post",
 5                     url: "TestMyOwnCheck", 
 6                     data: {
 7                         "id": "123",
 8                         "roleName": "mr12345"
 9                     },
10                     success: function (data) {
11                         if (data == "ok") {
12                             alert("測試經過");
13                         }
14                         if (data == "error") {
15                             alert("測試未經過");
16                         }
17                     }
18                 });
19             });
View Code

(3). 服務器端代碼

 1    public ActionResult TestDataAnnotationModel(UserInfor user)
 2         {
 3             //經過該方法進行驗證
 4             var isValidate = ModelState.IsValid;
 5 
 6             if (isValidate)
 7             {
 8                 return Content("ok");
 9             }
10             return Content("error");
11         }
View Code

 

四. Model級別的驗證擴展

   實現IValidaableObjec接口,實現Validate方法。(瞭解便可)

 1  public class CarInfor: IValidatableObject
 2     {
 3         public string id { get; set; }
 4 
 5         public string carName { get; set; }
 6 
 7         public int carAge { get; set; }
 8 
 9         IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
10         {
11             if (carAge % 2 == 0)
12             {
13                 var result = new ValidationResult("車齡驗證不經過", new string[] { "carAge" });
14 
15                 yield return result;
16             }
17         }
18     }

 

 

相關文章
相關標籤/搜索