zoukankan      html  css  js  c++  java
  • 能递归检查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代码下载

  • 相关阅读:
    myeclipse自带客户端连接mysql数据库
    javaweb学习总结八(xml约束DTD)
    javaweb学习总结七(XML语言作用、语法)
    javaweb学习总结六(泛型)
    plsql常用快捷键
    javaweb学习总结五(内省、beanUtils工具包)
    javaweb学习总结四(反射技术)
    javaweb学习总结三(枚举)
    eclipse常用快捷键汇总
    plsql设置窗口默认格式
  • 原文地址:https://www.cnblogs.com/aarond/p/Validate.html
Copyright © 2011-2022 走看看