枚举帮助方法,枚举数据注解自定义验证器
枚举辅助类
- 获取枚举项列表
- 获取枚举值列表
- 枚举项包含
- 枚举值包含
- 转换枚举
代码如下
1 /// <summary> 2 /// 枚举辅助类 3 /// </summary> 4 public class EnumHelper 5 { 6 7 private static readonly Dictionary<Type, object> EnumCache = new Dictionary<Type, object>(); 8 9 private static readonly Dictionary<Type, object> EnumValueCache = new Dictionary<Type, object>(); 10 /// <summary> 11 /// 取得枚举值列表 12 /// </summary> 13 public static List<T> GetEnumList<T>() 14 { 15 var t = typeof(T); 16 if (!t.IsEnum) 17 { 18 return null; 19 } 20 if (EnumCache.ContainsKey(t)) 21 { 22 return (List<T>)EnumCache[t]; 23 } 24 var arr = Enum.GetValues(t); 25 var values = new List<T>(); 26 var eor = arr.GetEnumerator(); 27 while (eor.MoveNext()) 28 { 29 values.Add((T)eor.Current); 30 } 31 EnumCache[t] = values; 32 return values; 33 } 34 35 /// <summary> 36 /// 取得枚举值列表 37 /// </summary> 38 public static List<int> GetEnumValueList<T>() 39 { 40 var t = typeof(T); 41 return GetEnumValueList(t); 42 } 43 44 /// <summary> 45 /// 取得枚举值列表 46 /// </summary> 47 public static List<int> GetEnumValueList(Type t) 48 { 49 if (!t.IsEnum) 50 { 51 return null; 52 } 53 54 if (EnumValueCache.ContainsKey(t)) 55 { 56 return (List<int>)EnumValueCache[t]; 57 } 58 var arr = Enum.GetValues(t); 59 var values = new List<int>(); 60 var eor = arr.GetEnumerator(); 61 while (eor.MoveNext()) 62 { 63 // ReSharper disable once PossibleNullReferenceException 64 values.Add((int)eor.Current); 65 } 66 EnumValueCache[t] = values; 67 return values; 68 69 } 70 71 /// <summary> 72 /// 枚举包含值 73 /// </summary> 74 public static bool EnumIncludeValue<T>(int val) 75 { 76 var enums = GetEnumValueList<T>(); 77 return enums != null && enums.Contains(val); 78 } 79 80 /// <summary> 81 /// 枚举包含值 82 /// </summary> 83 public static bool EnumInclude<T>(T val) 84 { 85 var enums = GetEnumList<T>(); 86 return enums != null && enums.Contains(val); 87 } 88 89 /// <summary> 90 /// 转换为枚举 91 /// </summary> 92 public static T ParseEnum<T>(int value) 93 { 94 return ParseEnum<T>(value.ToString()); 95 } 96 97 /// <summary> 98 /// 转换为枚举 99 /// </summary> 100 /// <param name="value">包含要转换的值或名称的字符串</param> 101 /// <returns>枚举</returns> 102 public static T ParseEnum<T>(string value) 103 { 104 return (T)Enum.Parse(typeof(T), value); 105 } 106 107 }
自定义了枚举值数据注解特性EnumValueAttribute
实现枚举值有效验证,如果枚举值不在枚举项中,则验证不通过。
1 /// <summary> 2 /// 枚举值正确性验证 3 /// </summary> 4 [AttributeUsage(AttributeTargets.Property)] 5 public class EnumValueAttribute : ValidationAttribute 6 { 7 /// <summary> 8 /// 是否需要验证上下文 9 /// </summary> 10 public override bool RequiresValidationContext => true; 11 12 /// <summary> 13 /// 是否有效 14 /// </summary> 15 /// <param name="value">要验证的枚举值</param> 16 /// <param name="validationContext">验证上下文</param> 17 /// <returns><see cref="ValidationResult"/>对象实例</returns> 18 protected override ValidationResult IsValid(object value, ValidationContext validationContext) 19 { 20 var t = value.GetType(); 21 if (!t.IsEnum) { ExceptionHelper.ThrowProgramException("EnumValue只能附加到枚举属性上",UtilityErrors.ProgramNotImplement);} 22 var values = EnumHelper.GetEnumValueList(t); 23 return !values.Contains((int)value) ? new ValidationResult(FormatErrorMessage(validationContext.MemberName)) : null; 24 } 25 }
单元测试代码
1 /// <summary> 2 /// 使用SharpZipLib来完成打包解包 3 /// </summary> 4 [TestClass] 5 public class ValidateTests 6 { 7 8 /// <summary> 9 /// 打包压缩文件夹测试 10 /// </summary> 11 [TestMethod] 12 public void ValidateTest() 13 { 14 TestEnums a = (TestEnums) 6; 15 TestEnums b = (TestEnums) 3; 16 var c=EnumHelper.GetEnumValueList<TestEnums>().Contains(6); 17 var containsA = EnumHelper.EnumInclude(a); 18 var containsB = EnumHelper.EnumInclude(b); 19 var model = new ValidateModel 20 { 21 AdminInitPassword = "123", 22 IntTest = 100, 23 Enum1 = 4, 24 Password1 = "12345", 25 Password2 = "123451", 26 RegexValue = "1235", 27 Nest = new NestModel { String1 = "string1" } 28 }; 29 // 获取验证结果列表 30 var results = model.GetValidateResults(); 31 32 Assert.IsTrue(results.Count == 6); 33 ////////// 验证模型是否有效 34 ////////bool valid = model.ValidateValid(); 35 ////////// 抛出验证结果集中的 第一条验证不通过信息 36 ////////model.ThrowValidateResult(); 37 ////////// 抛出验证结果集中的 所有验证不通过信息 38 ////////model.ThrowValidateResults(); 39 } 40 41 [CustomValidation(typeof(ValidateModel), "ValidateNestModel")] 42 public class NestModel 43 { 44 public string String1 { get; set; } 45 } 46 47 public class ValidateModel : IValidateModel 48 { 49 [Range(1000, 6000, ErrorMessage = "值要在1000-6000")] 50 public int IntTest { get; set; } 51 [MinLength(5, ErrorMessage = "至少五个字符")] 52 public string Password1 { get; set; } 53 [Compare("Password1", ErrorMessage = "两次密码不同")] 54 public string Password2 { get; set; } 55 [EmailAddress(ErrorMessage = "错误的邮件地址")] 56 public string Email { get; set; } 57 [RegularExpression(@"^\d{4}$", ErrorMessage = "格式错误")] 58 public string RegexValue { get; set; } 59 60 public int Enum1 { get; set; } 61 62 [EnumValue(ErrorMessage = "枚举值{0}无效")] 63 public TestEnums Enum2 => (TestEnums) Enum1; 64 65 /// <summary> 66 /// 管理员初始密码 67 /// </summary> 68 //[Required(ErrorMessage = "请输入密码")] 69 //[CustomValidation(typeof(ValidateModel), "ValidateAdminInitPassword")] 70 [CustomValidator(CustomValidatorKeys.TestCustomValidator)] 71 //[StringLength(60, MinimumLength = 20, ErrorMessage = "20-60个字符")] 72 public string AdminInitPassword { get; set; } 73 74 //[Required(ErrorMessage = "对象为空")] 75 //[CustomValidation(typeof(ValidateModel), "ValidateNestModel")] 76 public NestModel Nest { get; set; } 77 78 public static ValidationResult ValidateAdminInitPassword(string pwd, ValidationContext context) 79 { 80 var isValid = pwd == "123456"; 81 if (isValid) 82 { 83 return ValidationResult.Success; 84 } 85 86 return new ValidationResult("2密码不是123456"); 87 } 88 89 public static ValidationResult ValidateNestModel(NestModel model, ValidationContext context) 90 { 91 var isValid = model.String1 == "string2"; 92 if (isValid) 93 { 94 return ValidationResult.Success; 95 } 96 97 return new ValidationResult("嵌套对象自定义验证不通过"); 98 } 99 100 } 101 102 public enum TestEnums 103 { 104 Item1 = 1, 105 Item2 = 2, 106 Item3 = 3 107 } 108 109 }
文章作者:花生(OutMan)
发布地址:http://www.cnblogs.com/WangHuaiSheng/ 发布时间:2018-09-15 本文版权归作者和博客园共有,欢迎转载, 但未经作者同意必须保留此段声明, 且在文章页面明显位置给出原文连接。 |