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

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

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

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

     

      

  • 相关阅读:
    JavaScript之HTML DOM Event
    JavaScript 之 Function
    JavaScript 之 "for"的衍生对象
    Javascript object.constructor属性与面向对象编程(oop)
    前端发展简史
    基于MPI的大规模矩阵乘法问题
    Spark-shell错误:Missing Python executable 'python', defaulting to ...
    外文期刊论文的写法精概——“终极八股文大法!!!”
    Java静态方法为什么不能访问非静态方法
    API & Web API
  • 原文地址:https://www.cnblogs.com/WangHuaiSheng/p/EnumHelper.html
Copyright © 2011-2022 走看看