摘要
你還在為了驗證一個Class對象中很多數據的有效性而寫很多If條件判斷嗎?我也同樣遇到這種問題,不過,最近學了一項新的方法,讓我不在寫很多if條件做判斷,通過給屬性標注特性來驗證數據規則,從此再也不需要寫很多If條件判斷了。
最近寫C#項目中的時候,在驗證數據的有效性的時候寫了很多判斷,結果工作量很大,然后就想能實現在類屬性上標示驗證的特性,來驗證數據的有效性,以前聽說過,但是從來沒有實現過,也很少看到在項目中別人使用過,所以就一直沒有研究過,但是最近在寫Model的時候需要驗證很多數據的有效性,所以就想研究一下。
需求:將類屬性標示一個驗證特性,在使用該類的時候驗證數據的有效性,
我是使用了控制台應用程序做測試,首先我的思路是將Class的屬性標示上特性,用來驗證屬性的數據規則,
這里定義了一個驗證特性,主要是來標示屬性的最大長度,和當大於最大長度是得提示信息。
/// <summary> /// 指定數據字段中允許的最小和最大字符長度。 /// </summary> public class StringLengthAttribute : Attribute { /// <summary> /// 獲取或設置字符串的最大長度。 /// </summary> public int MaximumLength { get; set; }/// <summary> /// 消息提示 /// </summary> public string ErrorMessage { get; set; } /// <summary> /// /// </summary> /// <param name="maximumLength"></param> public StringLengthAttribute(int maximumLength) { MaximumLength = maximumLength; } }
這里是用來驗證的類
/// <summary> /// 數據模型 /// </summary> public class DataModel : MyIsValid<DataModel> { /// <summary> /// 值 /// </summary> [StringLength(5, ErrorMessage = "Value最大長度為5")] public string Value { get; set; } }
然后我就寫了一個基類,統統的在基類中做驗證。下面是基類的代碼,打算以后所有的需要做驗證的類,都繼承該基類,將屬性標識上特性做驗證呢(后來發現更好的辦法),寫的不好,還請多多指教。
public class MyIsValid<T> where T : class { //驗證信息 internal string Msg { get; set; } // 驗證是否有效 internal bool IsValid() { var v = this as T; Type type = v.GetType(); PropertyInfo[] propeties = type.GetProperties(); foreach (PropertyInfo property in propeties) { List<Attribute> attributes = property.GetCustomAttributes().ToList(); var propertyValue = property.GetValue(v); Attribute stringlength = attributes.FirstOrDefault(p => p.GetType().IsAssignableFrom(typeof(StringLengthAttribute))); if (stringlength == null) continue; int length = ((StringLengthAttribute)stringlength).MaximumLength; string currentValue = (string)propertyValue; if (currentValue.Length > length) { Msg = ((StringLengthAttribute)stringlength).ErrorMessage; return false; } } return true; } }
然后執行結果如圖:
執行結果還行,只不過還需要對基類做擴展,支持針對不同的特性做不同的驗證。
然后我想到了Asp.Net MVC 里面使用的數據模型綁定技術,然后就想能不能使用它的現有的方法,后來就發現了,“System.ComponentModel.DataAnnotations”這個
具體參考:https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validator.aspx
然后針對我的需求寫了一個擴展方法,如下.(注意一定要引用:System.ComponentModel.DataAnnotations;)
public static class ExtensionHelper { /// <summary> /// 驗證對象是否有效 /// </summary> /// <param name="obj">要驗證的對象</param> /// <param name="validationResults"></param> /// <returns></returns> public static bool IsValid(this object obj, Collection<ValidationResult> validationResults) { return Validator.TryValidateObject(obj, new ValidationContext(obj, null, null), validationResults, true); } /// <summary> /// 驗證對象是否有效 /// </summary> /// <param name="obj">要驗證的對象</param> /// <returns></returns> public static bool IsValid(this object obj) { return Validator.TryValidateObject(obj, new ValidationContext(obj, null, null), new Collection<ValidationResult>(), true); } }
使用方式如下:
驗證相關特性:https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx
也可以自定義,
class Program { static void Main(string[] args) { DataModel r = new DataModel(); r.EmailAddress = "cdaimesdfng1m"; var v = new Collection<ValidationResult>(); if (r.IsValid(v)) { Console.WriteLine("1"); } else { v.ToList().ForEach(e => { Console.WriteLine(e.ErrorMessage); }); } Console.ReadKey(); } } public class DataModel { /// <summary> /// /// </summary> [Required] [StringLength(5, ErrorMessage = "太大")] public string Name { get; set; } /// <summary> /// /// </summary> [Range(2, 5)] public string d { get; set; } /// <summary> /// /// </summary> [EmailAddress] public string EmailAddress { get; set; } }
Demo下載地址:http://download.csdn.net/detail/u014265946/9330181