zoukankan      html  css  js  c++  java
  • C# 利用特性(Attribute)实现通用实体类数据合法校验

    用过asp.net mvc 的都应该知道,在实体类上添加一些特性,可以实现后端实体的数据校验,这里简单实现一下

    实现原理:利用反射获取实体的每一个属性,并通过属性获取属性上标注的特性,调用特性的Validate方法(此方法自定义的)来验证属性的值是否合法。

    1、创建自己的校验特性基类

    此类继承了Attribute,表明为一个特性,Validate方法为抽象方法,目的是给实现的子类自己定义自己的Validate方法。error为错误消息提示信息。

    1 [AttributeUsage(AttributeTargets.Property,AllowMultiple = true)]
    2     public abstract class BaseAttribute:Attribute
    3     {
    4         public virtual string error { get; set; }
    5         public abstract bool Validate(object value);
    6     }

    2、创建特性类继承自BaseAttribute

    这里只简单写3个特性,写法都一样,只是校验方法Validate中的逻辑不一样。

     1 /// <summary>
     2     /// 约束属性不能为空
     3     /// </summary>
     4     public class RequiredAttribute : BaseAttribute
     5     {
     6         public override string error {
     7             get
     8             {
     9                 if (base.error != null)
    10                 {
    11                     return base.error;
    12                 }
    13                 return "属性不能为空";
    14             }
    15             set => base.error = value;
    16         }
    17         public override bool Validate(object value)
    18         {
    19             return !(value == null);
    20         }
    21     }
     1 /// <summary>
     2     /// 约束字符串的长度范围
     3     /// </summary>
     4     public class StringRangeAttribute : BaseAttribute
     5     {
     6         public int min { get; set; }
     7         public int max { get; set; }
     8         public override string error {
     9             get {
    10                 if (base.error != null)
    11                 {
    12                     return base.error;
    13                 }
    14                 return $"字符串长度范围{this.min}-{this.max}";
    15             }
    16             set => base.error = value; }
    17         public override bool Validate(object value)
    18         {
    19             return value.ToString().Length >= this.min && value.ToString().Length <= this.max;
    20         }
    21     }
     1 /// <summary>
     2     /// 约束符合正则表达式
     3     /// </summary>
     4     public class RegexAttribute : BaseAttribute
     5     {
     6         public string regexText;
     7         public override bool Validate(object value)
     8         {
     9             var regex = new Regex(regexText);
    10             return regex.Match(value.ToString()).Success;
    11         }
    12     }

    3、给实体类扩展一个方法,用来验证实体类实例属性值是否合法

    此方式的扩展方法会污染其他非实体类,不是太推荐用太多此种扩展写法,其实这里不写成扩展方法也没什么问题。

    此扩展方法会验证实例中的所有属性,并将所有不通过验证的属性的提示信息以字符串的形式返回,所有都验证通过则返回空串。

     1 public static string Validate<T>(this T t)
     2         {
     3             Type type = t.GetType();
     4 
     5             //获取所有属性
     6             PropertyInfo[] propertyInfos = type.GetProperties(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
     7             List<string> errorList = new List<string>();
     8             foreach (PropertyInfo propertyInfo in propertyInfos)
     9             {
    10                 if(propertyInfo.IsDefined(typeof(BaseAttribute)))//如果属性上有定义该属性,此步没有构造出实例
    11                 {
    12                     foreach (BaseAttribute attribute in propertyInfo.GetCustomAttributes(typeof(BaseAttribute)))
    13                     {
    14                         if (!attribute.Validate(propertyInfo.GetValue(t, null)))
    15                         {
    16                             errorList.Add( $"[{propertyInfo.Name}]" + attribute.error);
    17                         }
    18                     }
    19                     
    20                 }
    21             }
    22             return string.Join(",", errorList);
    23         }

    4、定义一个实体类,并测试(控制台程序)。

    假设有Student.cs ,在其id属性中添加Required特性,name属性上添加StringRange和Regex特性。

    1 public class Student
    2     {
    3         [Required(error = "id 不能为空!")]
    4         public int? id { get; set; }
    5         [Regex(regexText = "^a.*a$",error = "属性不合格规则")]
    6         [StringRange(min =5,max =10)]
    7         public string name { get; set; }
    8     }
     1 static void Main(string[] args)
     2         {
     3             Student student = new Student()
     4             {
     5                 id = null,
     6                 name = "ajiudsagasgasgaxb"
     7             };
     8             string errorStr = student.Validate();
     9             Console.WriteLine(errorStr);
    10             Console.ReadKey();
    11         }

    测试结果

    此代码纯属自己理解的原理性还原,代码可能有多处写的不严谨。

  • 相关阅读:
    $('div div')和$('div >div')的区别
    [转]35岁前程序员要规划好的四件事,健康居首位
    程序员应该改变的20个思维习惯
    JQuery总结
    Javahome 与 Path 与ClassPath的含义
    jsp 位置
    访问 IIS 元数据库失败 权限问题
    xp添加文件夹写入权限
    dataset 对象
    js的一些代码
  • 原文地址:https://www.cnblogs.com/fnz0/p/11387835.html
Copyright © 2011-2022 走看看