zoukankan      html  css  js  c++  java
  • 参数声明式校验

    用户输入都是不可信的,我想,大多数后端开发人员,都有这么一个共识。

    然后,在写每一个方法的时候,基本都会有一坨if校验,我也不例外。

    代码写多了,有时候就会想,能不能优化下,能不能优雅点?

    于是,我又开始寻寻觅觅...

    这个,就是,声明式验证...

    以下是我整理的代码:

    声明式验证核心部分:

    1     public enum ValidateType
    2     {
    3         IsString = 10000,
    4         IsInt32 = 20000,
    5         IsDecimal = 30000,
    6         IsDateTime = 40000,
    7         IsBoolean = 50000,
    8     }
      1     [AttributeUsage(AttributeTargets.All)]
      2     public class ValidateAttribute : Attribute
      3     {
      4         //是否必填
      5         private bool isRequired = true;
      6         //最小长度
      7         private int minLength = 0;
      8         //最大长度
      9         private int maxLength = Int32.MaxValue;
     10         //字段指定长度
     11         private int stringLength = Int32.MaxValue;
     12         //验证类型
     13         private ValidateType validateType;
     14 
     15         /// <summary>
     16         /// 显示名称
     17         /// </summary>
     18         public string DisplayName { get; set; }
     19 
     20         /// <summary>
     21         /// 是否必填
     22         /// </summary>
     23         public bool IsRequired
     24         {
     25             get
     26             {
     27                 return isRequired;
     28             }
     29             set
     30             {
     31                 isRequired = value;
     32             }
     33         }
     34 
     35         /// <summary>
     36         /// 最小长度
     37         /// </summary>
     38         public int MinLength
     39         {
     40             get
     41             {
     42                 return minLength;
     43             }
     44             set
     45             {
     46                 minLength = value;
     47             }
     48         }
     49 
     50         /// <summary>
     51         /// 最大长度
     52         /// </summary>
     53         public int MaxLength
     54         {
     55             get
     56             {
     57                 return maxLength;
     58             }
     59             set
     60             {
     61                 maxLength = value;
     62             }
     63         }
     64 
     65         /// <summary>
     66         /// 字段指定长度
     67         /// </summary>
     68         public int StringLength
     69         {
     70             get
     71             {
     72                 return stringLength;
     73             }
     74             set
     75             {
     76                 stringLength = value;
     77             }
     78         }
     79 
     80         /// <summary>
     81         /// 正则表达式校验格式
     82         /// </summary>
     83         public string RegexpCheckFormat { get; set; }
     84 
     85         /// <summary>
     86         /// 正则表达式显示格式
     87         /// </summary>
     88         public string RegexpDisplayFormat { get; set; }
     89 
     90         /// <summary>
     91         /// Int32集合
     92         /// </summary>
     93         public int[] Int32Collection { get; set; }
     94 
     95         /// <summary>
     96         /// 字符串集合
     97         /// </summary>
     98         public string[] StringCollection { get; set; }
     99 
    100         /// <summary>
    101         /// 验证类型
    102         /// </summary>
    103         public ValidateType ValidateType
    104         {
    105             get
    106             {
    107                 return validateType;
    108             }
    109             set
    110             {
    111                 validateType = value;
    112             }
    113         }
    114 
    115         /// <summary>
    116         /// 构造函数
    117         /// </summary>
    118         /// <param name="validateType"></param>
    119         public ValidateAttribute(ValidateType validateType)
    120         {
    121             this.validateType = validateType;
    122         }
    123     }
    View Code
      1     public static class ValidateHandler
      2     {
      3         /// <summary>
      4         /// 获得结果
      5         /// </summary>
      6         /// <param name="instance">类对象实例</param>
      7         /// <returns></returns>
      8         public static string GetResultString(object instance)
      9         {
     10             var result = string.Empty;
     11             if (instance.IsNull())
     12             {
     13                 return "instance 参数不能为空";
     14             }
     15             Type type = instance.GetType();
     16             PropertyInfo[] properties = type.GetProperties();
     17             foreach (PropertyInfo property in properties)
     18             {
     19                 //获取验证特性
     20                 object[] validAttrs = property.GetCustomAttributes(typeof(ValidateAttribute), true);
     21                 if (!validAttrs.IsNull())
     22                 {
     23                     //获取属性的值
     24                     object propVal = property.GetValue(instance, null);
     25                     //属性值长度
     26                     int propValLength = 0;
     27                     foreach (ValidateAttribute validAttr in validAttrs)
     28                     {
     29                         //获取属性名称
     30                         var propName = !validAttr.DisplayName.IsNullOrEmptyOrWhiteSpace() ? validAttr.DisplayName : property.Name;
     31                         //校验是否必填
     32                         if (validAttr.IsRequired)
     33                         {
     34                             if (propVal.IsNull())
     35                             {
     36                                 return "{0} 字段是必需的".FormatWith(propName);
     37                             }
     38                             if (validAttr.ValidateType == ValidateType.IsString
     39                                 && propVal.ToString().IsNullOrEmptyOrWhiteSpace())
     40                             {
     41                                 return "{0} 字段是必需的".FormatWith(propName);
     42                             }
     43                             if (validAttr.ValidateType == ValidateType.IsInt32
     44                                 && !propVal.IsInt32())
     45                             {
     46                                 return "{0} 字段不是Int32类型".FormatWith(propName);
     47                             }
     48                             if (validAttr.ValidateType == ValidateType.IsDecimal
     49                                 && !propVal.IsDecimal())
     50                             {
     51                                 return "{0} 字段不是Decimal类型".FormatWith(propName);
     52                             }
     53                             if (validAttr.ValidateType == ValidateType.IsDateTime)
     54                             {
     55                                 if (!propVal.IsDateTime())
     56                                 {
     57                                     return "{0} 字段不是日期类型".FormatWith(propName);
     58                                 }
     59                                 if (propVal.ToDateTime() == DateTime.MinValue)
     60                                 {
     61                                     return "{0} 字段是必需的".FormatWith(propName);
     62                                 }
     63                             }
     64                             if (validAttr.ValidateType == ValidateType.IsBoolean
     65                                 && !propVal.IsBoolean())
     66                             {
     67                                 return "{0} 字段不是布尔类型".FormatWith(propName);
     68                             }
     69                         }
     70                         propValLength = propVal.IsNull() ? 0 : propVal.ToString().Length;
     71                         //校验最小长度
     72                         if (propValLength < validAttr.MinLength)
     73                         {
     74                             return "{0} 字段或数组长度不能小于{1}".FormatWith(propName, validAttr.MinLength);
     75                         }
     76                         //校验最大长度
     77                         if (propValLength > validAttr.MaxLength)
     78                         {
     79                             return "{0} 字段或数组长度不能大于{1}".FormatWith(propName, validAttr.MaxLength);
     80                         }
     81                         if (validAttr.StringLength != Int32.MaxValue
     82                             && propValLength != validAttr.StringLength)
     83                         {
     84                             return "{0} 字段长度错误,长度必须为{1}".FormatWith(propName, validAttr.StringLength);
     85                         }
     86                         //校验正则表达式
     87                         if (!validAttr.RegexpCheckFormat.IsNullOrEmptyOrWhiteSpace())
     88                         {
     89                             if (!Regex.IsMatch(propVal.ToString(), validAttr.RegexpCheckFormat))
     90                             {
     91                                 if (!validAttr.RegexpDisplayFormat.IsNull())
     92                                 {
     93                                     return "{0} 字段格式错误,正确格式为{1}".FormatWith(propName, validAttr.RegexpDisplayFormat);
     94                                 }
     95                                 else
     96                                 {
     97                                     return "{0} 字段格式错误".FormatWith(propName);
     98                                 }
     99                             }
    100                         }
    101                         //校验集合
    102                         if (propVal.IsInt32()
    103                             && !validAttr.Int32Collection.IsNull()
    104                             && !validAttr.Int32Collection.Contains(propVal.ToInt32()))
    105                         {
    106                             return "{0} 字段必须为 {1} 中的一个".FormatWith(propName, string.Join(",", validAttr.Int32Collection));
    107                         }
    108                         if (!validAttr.StringCollection.IsNull()
    109                             && !validAttr.StringCollection.Contains(propVal.ToString()))
    110                         {
    111                             return "{0} 字段必须为 {1} 中的一个".FormatWith(propName, string.Join(",", validAttr.Int32Collection));
    112                         }
    113                     }
    114                 }
    115             }
    116             return string.Empty;
    117         }
    118     }
    View Code

    有一个需要验证的资源类:

     1     public class ResourceDto
     2     {
     3         [Validate(ValidateType.IsDateTime, IsRequired = false)]
     4         public string ResoCreateTime { get; set; }
     5 
     6         [Validate(ValidateType.IsString, IsRequired = false)]
     7         public string ResoDesc { get; set; }
     8 
     9         [Validate(ValidateType.IsString, IsRequired = false)]
    10         public string ResoId { get; set; }
    11 
    12         [Validate(ValidateType.IsBoolean, DisplayName = "是否显示")]
    13         public string ResoIsShow { get; set; }
    14 
    15         [Validate(ValidateType.IsString, DisplayName = "资源名称")]
    16         public string ResoName { get; set; }
    17 
    18         [Validate(ValidateType.IsInt32, DisplayName = "资源排序")]
    19         public string ResoOrder { get; set; }
    20 
    21         [Validate(ValidateType.IsString, DisplayName = "父资源ID")]
    22         public string ResoParentId { get; set; }
    23 
    24         [Validate(ValidateType.IsString, DisplayName = "资源类型")]
    25         public string ResoType { get; set; }
    26 
    27         [Validate(ValidateType.IsDateTime, IsRequired = false)]
    28         public string ResoUpdateTime { get; set; }
    29 
    30         [Validate(ValidateType.IsString, IsRequired = false)]
    31         public string ResoUrl { get; set; }
    32     }

    控制器保存数据校验部分:

     1         public void ResourceSave()
     2         {
     3             //...
     4             ResourceDto model = new JavaScriptSerializer().Deserialize<ResourceDto>("FormData".ValueOfForm());
     5             var checkResult = ValidateHandler.GetResultString(model);
     6             if (checkResult != string.Empty)
     7             {
     8                 //以下是处理错误的代码
     9                 return;
    10             }
    11             //...
    12         }

    使用声明式验证,代码有没有简洁美观点?哈哈。

  • 相关阅读:
    自动化测试先关
    hadoop集群(第二节机器信息分布表)
    hadoop集群(第一节)
    SpringCloud微服务架构学习笔记
    SpringBoot启动一个项目
    VUE框架介绍
    SpringMVC配置与使用
    Spring学习笔记(二)
    8、XML与JSON
    7、主页面访问权限控制
  • 原文地址:https://www.cnblogs.com/maiaimei/p/7246368.html
Copyright © 2011-2022 走看看