• 能递归检查DataAnnotations的验证函数


    有时在Command和DTO之间层次比较多,写了个验证Command的函数,能实现递归验证.

    比如下面这些有层级关系的class定义,能通过一句代码来进行验证:

    class A
        {
            [Required]
            public B B { get; set; }
        }
    
        class B
        {
            [Range(10, 20)]
            public int C { get; set; }
    
            [Range(typeof(Guid), "00000000-0000-0000-0000-000000000001", "00000000-0000-0000-0000-000000000010")]
            public Guid aa { get; set; }
    
            public CC ddd { get; set; }
        }
        class CC
        {
            [Range(10, 20)]
            public int DDDDD { get; set; }
    
            [Required(ErrorMessage = "必须填写用户名")]
            [Display(Name = "用户名")]
            public string UserName { get; set; }
    
            [Required(ErrorMessage = "必须填写密码")]
            [DataType(DataType.Password)]
            [Display(Name = "密码")]
            public string Password { get; set; }
        }

    验证函数调用:

    List<BrokenRule> errors = obj.IsValid();

    代码如下:

    public class BrokenRule
        {
            public string Key { get; set; }
            public string Message { get; set; }
        }
    
        public static class DataAnnotationHelper
        {
            public static List<BrokenRule> IsValid<T>(this T o, bool only1Level = false)
            {
                return IsValid(typeof(T), o, only1Level);
            }
    
            private static List<BrokenRule> IsValid(Type t, object o, bool only1Level)
            {
                List<BrokenRule> errors = new List<BrokenRule>();
    
                var descriptor = GetTypeDescriptor(t);
    
                foreach (PropertyDescriptor propertyDescriptor in descriptor.GetProperties())
                {
                    foreach (var validationAttribute in propertyDescriptor.Attributes.OfType<ValidationAttribute>())
                    {
                        if (!validationAttribute.IsValid(propertyDescriptor.GetValue(o)))
                        {
                            BrokenRule error = new BrokenRule();
                            error.Key = propertyDescriptor.Name;
                            error.Message = validationAttribute.FormatErrorMessage(propertyDescriptor.Name);
                            errors.Add(error);
                        }
                    }
                }
    
                if (!only1Level)
                {
                    if (o.GetType().IsClass&&!o.GetType().Equals(typeof(string)))
                    {
                        foreach (var p in o.GetType().GetProperties())
                        {
                            object pValue = p.GetValue(o, null);
                            if (pValue != null)
                            {
                                List<BrokenRule> pErrors = IsValid(p.PropertyType, pValue, only1Level);
                                errors.AddRange(pErrors);
                            }
                        }
                    }
                }
    
                return errors;
            }
            private static ICustomTypeDescriptor GetTypeDescriptor(Type type)
            {
                return new AssociatedMetadataTypeTypeDescriptionProvider(type).GetTypeDescriptor(type);
            }
        }

     效果图:

     

     完整demo代码下载

  • 相关阅读:
    很火的华为太空表网站源码
    exists用法 exists用法讲解
    mysql 建立索引在on 从句中_MySQL优化
    mysql on 条件会走索引吗
    【算法理论】动归入门[C语言描述]
    机器学习基础考试复习
    【基础知识】深度学习500问之生成对抗网络
    【王道数据结构】《王道数据结构》课后代码题汇总
    【C语言实现】数据结构算法题及答案
    【题目归档】考研数据结构算法题目归档
  • 原文地址:https://www.cnblogs.com/aarond/p/Validate.html
Copyright © 2020-2023  润新知