验证API

验证API

本篇定位在数据入口的验证

  1. 普通的DataAnnotation验证
  2. 基于场景的DataAnnotation验证
  3. 可修改的外置式DataAnnotation验证

SUMMARY

 最终调用时的用法:

复制代码
class Program
    {
        static void Main(string[] args)
        {
            A2DFramework.Starter.Init();
            A2DFramework.RuleEngine.Starter.Init();
            A2DFramework.BusinessExceptionService.Starter.Init();

            User user = new User();
            user.FirstName = "aaa";
            user.CustomField = "aaron";
            foreach (var error in user.IsValid())
            {
                Console.WriteLine(error.Key);
            }
            Console.WriteLine("===================");
            foreach (var error in user.IsValid("场景1"))
            {
                Console.WriteLine(error.Key);
                Console.WriteLine(error.Message);
            }

            Console.ReadKey();
        }
    }
复制代码

 原理:

基于场景的验证特性实现,举例:RuleDataTypeAttribute

RuleDataTypeAttribute,也就是DataTypeAttribute的场景支持版:

复制代码
/// <summary>
    /// 支持规则场景的验证基类
    /// </summary>
    public class RuleValidationAttribute : ValidationAttribute
    {
        public RuleValidationAttribute()
        {
            this.RuleName = string.Empty;
        }

        public RuleValidationAttribute(string rule)
        {
            this.RuleName = rule;
        }

        public string RuleName { get; set; }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            return base.IsValid(value, validationContext);
        }
    }


public class RuleDataTypeAttribute : RuleValidationAttribute
    {
        private DataTypeAttribute checker;

        public RuleDataTypeAttribute(DataType dataType):this(string.Empty, dataType)
        {
        }
        public RuleDataTypeAttribute(string rule, DataType dataType):base(rule)
        {
            checker = new DataTypeAttribute(dataType);
        }

        public RuleDataTypeAttribute(string rule, string customDataType)
            : base(rule)
        {
            checker = new DataTypeAttribute(customDataType);
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            return checker.GetValidationResult(value, validationContext);
        }
    }
复制代码

至于基于RuleName的执行验证代码,核心代码:

复制代码
List<BrokenRule> errors = new List<BrokenRule>();

            var descriptor = GetTypeDescriptor(t);

            foreach (PropertyDescriptor propertyDescriptor in descriptor.GetProperties())
            {
                foreach (var validationAttribute in propertyDescriptor.Attributes.OfType<ValidationAttribute>())
                {
                    RuleValidationAttribute baseAttr = validationAttribute as RuleValidationAttribute;
                    if (baseAttr != null)
                    {
                        //支持场景验证
                        if (baseAttr.RuleName.Equals(scene, StringComparison.OrdinalIgnoreCase))
                        {
                            ValidateProperty(o, errors, propertyDescriptor, validationAttribute);
                        }
                    }
                    else
                    {
                        //不支持场景的验证
                        ValidateProperty(o, errors, propertyDescriptor, validationAttribute);
                    }
                }
            }


private void ValidateProperty(object o, List<BrokenRule> errors, PropertyDescriptor propertyDescriptor, ValidationAttribute validationAttribute)
        {
            object obj = propertyDescriptor.GetValue(o);
            ValidationContext ctx = new ValidationContext(o, null, null);
            ValidationResult result = validationAttribute.GetValidationResult(obj, ctx);
            if (result != ValidationResult.Success)
            {
                BrokenRule error = new BrokenRule();
                error.Key = propertyDescriptor.Name;
                error.Message = validationAttribute.FormatErrorMessage(propertyDescriptor.Name);
                errors.Add(error);
            }
        }
复制代码

 上述代码是实现C#硬编码的验证逻辑,关于外置验证逻辑其实就是上述的另外一份拷贝,只是把里面的某些函数redirect到xml中,略。

 具体文本验证逻辑的执行是通过调用js引擎实现,都比较简单。

 稍微修改就能实现分布式和统一管理。

原文地址:https://www.cnblogs.com/Leo_wl/p/3592908.html