zoukankan      html  css  js  c++  java
  • 枚举帮助方法,枚举数据注解自定义验证器

    枚举辅助类

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

    代码如下

      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

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

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

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

     

      

  • 相关阅读:
    NOIP201208同余方程
    NOIP模拟赛 最佳组合
    NOIP模拟赛 拓展
    CF1253E Antenna Coverage(DP)
    LOJ6033「雅礼集训 2017 Day2」棋盘游戏 (博弈论,二分图,匈牙利算法)
    CF582E Boolean Function(DP,状态压缩,FMT)
    CF750G New Year and Binary Tree Paths(DP)
    Codeforces Round 596 题解
    AGC008E Next or Nextnext(组合计数,神奇思路)
    ARC082E ConvexScore(神奇思路)
  • 原文地址:https://www.cnblogs.com/WangHuaiSheng/p/EnumHelper.html
Copyright © 2011-2022 走看看