.NET中特性+反射 实现数据校验

  • .NET中特性+反射 实现数据校验已关闭评论
  • 67 次浏览
  • A+
所属分类:.NET技术
摘要

在.NET中,我们可以使用特性+反射来实现数据校验。特性是一种用于为程序中的代码添加元数据的机制。元数据是与程序中的代码相关联的数据,但不直接成为代码的一部分。通过特性,我们可以为类、方法、属性等添加额外的信息,这些信息可以在运行时通过反射获取和使用。
对反射不太熟悉的小伙伴可以去看我以前的文章 .NET中的反射


.NET中特性+反射 实现数据校验

在.NET中,我们可以使用特性+反射来实现数据校验。特性是一种用于为程序中的代码添加元数据的机制。元数据是与程序中的代码相关联的数据,但不直接成为代码的一部分。通过特性,我们可以为类、方法、属性等添加额外的信息,这些信息可以在运行时通过反射获取和使用。
对反射不太熟悉的小伙伴可以去看我以前的文章 .NET中的反射

为了实现数据校验,我们可以定义一个自定义特性,并将其应用于需要校验的属性或参数上。然后,我们可以编写代码来检查这些特性,并根据特性的配置执行相应的校验逻辑。

示例代码

定义自定义特性

using System; using System.ComponentModel.DataAnnotations;  [AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)] public class ValidationAttribute : Attribute  {       public string ErrorMessage { get; set; }        public ValidationAttribute(string errorMessage)       {           ErrorMessage = errorMessage;       } } 

定义具体的校验特性

[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)] public class RequiredAttribute : ValidationAttribute   {       public RequiredAttribute() : base("该字段是必填项。") { }   }      [AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)] public class RangeAttribute : ValidationAttribute   {       public int Minimum { get; set; }       public int Maximum { get; set; }        public RangeAttribute(int minimum, int maximum, string errorMessage = "该字段的值必须在 {0} 和 {1} 之间。")            : base(errorMessage)       {           Minimum = minimum;           Maximum = maximum;       } } 

在模型类中使用这些特性

public class Person   {       [Required]     public string Name { get; set; }        [Range(18, 100, ErrorMessage = "年龄必须在 18 到 100 之间。")]     public int Age { get; set; } } 

编写验证方法

public class Validator   {       public static bool Validate<T>(T obj, out string errorMessage)       {           errorMessage = null;           var type = typeof(T);           var properties = type.GetProperties();              foreach (var property in properties)           {               var validationAttributes = property.GetCustomAttributes(typeof(ValidationAttribute), true);                  foreach (var attribute in validationAttributes)               {                   var value = property.GetValue(obj);                      switch (attribute)                   {                       case RequiredAttribute required:                           if (value == null || (value is string str && string.IsNullOrWhiteSpace(str)))                           {                               errorMessage = required.ErrorMessage;                               return false;                           }                           break;                       case RangeAttribute range:                           if (value is IComparable comparable)                           {                               if (comparable.CompareTo(range.Minimum) < 0 || comparable.CompareTo(range.Maximum) > 0)                               {                                   errorMessage = string.Format(range.ErrorMessage, range.Minimum, range.Maximum);                                   return false;                               }                           }                           break;                       // 可以添加更多校验特性类型                   }               }           }              return true;       }   } 

使用Validator类来校验Person对象

class Program {     static void Main(string[] args)     {         var person = new Person { Name = "张三", Age = 15 };         string errorMessage;         bool isValid = Validator.Validate(person, out errorMessage);         if (!isValid)         {             Console.WriteLine(errorMessage); // 输出:该字段是必填项。         }         Console.ReadLine();     } } 

说明

这个示例演示了如何使用特性和反射实现基本的数据校验。在实际应用中,你可能需要处理更复杂的校验逻辑和更多的校验类型。

此外,还可以使用现有的数据特性(如System.ComponentModel.DataAnnotations命名空间中的特性)来简化校验过程。
以下是该命名空间中一些常用的特性(Attribute),以及它们的用途:

特性名称 用途
[Required] 确保属性值不为空(不为 null 且对于字符串不是空字符串)。
[StringLength] 限制字符串属性的最大长度。
[Range] 确保数值型属性在指定的范围内。
[Minimum] 确保数值型属性不小于指定的最小值。
[Maximum] 确保数值型属性不大于指定的最大值。
[RegularExpression] 通过正则表达式验证属性值的格式。
[EmailAddress] 验证属性值是否为有效的电子邮件地址。
[Url] 验证属性值是否为有效的 URL。
[Phone] 验证属性值是否为有效的电话号码。
[CreditCard] 验证属性值是否为有效的信用卡号。
[Compare] 比较两个属性值是否相等,常用于密码和确认密码的字段。
[DataType] 指定数据的类型,例如日期、时间、电话号码等,并不验证数据,而是提供给数据绑定机制。
[CustomValidation] 允许指定自定义验证逻辑。
[EnumDataType] 验证属性值是否为指定枚举类型中的有效成员。
[StringLength] 验证字符串长度是否在指定的范围内。

这些特性通常与ASP.NET Core或是ASP.NET MVC、Entity Framework等框架结合使用。
使用这些特性可以大大简化数据验证的代码,并且使验证逻辑与业务逻辑分离,提高代码的可维护性和可读性。