一. 簡介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 }
(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 });
(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 }
三. 自定義數據批註
思路:經過上面的批註源碼可知,均爲自定義類繼承: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 }
(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 });
(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 }
四. 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 }