枚举帮助方法,枚举数据注解自定义验证器

Posted wanghuaisheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了枚举帮助方法,枚举数据注解自定义验证器相关的知识,希望对你有一定的参考价值。

枚举辅助类

  • 获取枚举项列表
  • 获取枚举值列表
  • 枚举项包含
  • 枚举值包含
  • 转换枚举

代码如下

  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     }
View Code

 

 


技术分享图片  文章作者:花生(OutMan)

发布地址:http://www.cnblogs.com/WangHuaiSheng/ 

发布时间:2018-09-15

本文版权归作者和博客园共有,欢迎转载,

但未经作者同意必须保留此段声明,

且在文章页面明显位置给出原文连接。

 

  

以上是关于枚举帮助方法,枚举数据注解自定义验证器的主要内容,如果未能解决你的问题,请参考以下文章

想必大家在做参数验证的时候,都会遇到一个问题,就是如何验证枚举? 自定义annotation 自定义Validator

SpringBoot系列之自定义枚举类的数据校验注解

Java之枚举注解反射

学妹问我Java枚举类与注解,我直接用这个搞定她!

学妹问我Java枚举类与注解,我直接用这个搞定她!

SpringBoot系列之自定义枚举类的数据校验注解