[Architect] Abp 框架原理解析(4) Validation


本節目錄

 

介紹

Abp中在Application層集成了validation.

直接上代碼吧.

 

DataAnnotations

這是微軟提供的一套驗證框架,只用引用程序集System.ComponentModel.DataAnnotations.

自帶的各種特性標簽就不說了,默認在MVC中已集成此驗證.

這里說下驗證方法:

        static void Main(string[] args)
        {
            var obj = new object();
            var rst = new StringLengthAttribute(10) { MinimumLength = 6 }.GetValidationResult("Never", new ValidationContext(obj) { DisplayName = "名稱", MemberName = "Name" });
            Console.WriteLine(rst);
            Console.ReadKey();
        }

運行結果:

ValidationResult對象

在MVC中,obj指的是驗證的對象,DisplayName指DisplayName特性的Name值,Member指字段代碼名.

 

 

 
        

 

ICustomValidate

該接口在標准驗證結束后調用.

    public interface ICustomValidate : IValidate
    {
        void AddValidationErrors(List<ValidationResult> results);
    }

 

通常會如下操作:

    public class CreateTaskInput : IInput, ICustomValidate
    {
        public string Name { get; set; }
        public void AddValidationErrors(List<ValidationResult> results)
        {
            if (Name == "xx")
            {
                results.Add(new ValidationResult("Task 名非法"));
            }
        }
    }

 

 

當標准驗證功能無法完成某些特定的驗證功能,可以使用此接口.

 

 

IShouldNormalize

該接口並非驗證字段,而是在驗證完字段,離開驗證過濾器前的時候執行.

一般在此接口做初始化或者其他操作.

    public interface IShouldNormalize
    {
        void Normalize();
    }

如:

    public class CreateTaskInput : IInput, IShouldNormalize
    {
        public string Name { get; set; }
        public void Normalize()
        {
            Name = DateTime.Now.ToShortDateString() + "-task";
        }
    }

  

 

實現Abp Validation

在Abp中大致會經歷這3個接口.

在這里,仿照Abp驗證

 

先定義接口

    public interface IInput
    {

    }
    public interface IShouldNormalize
    {
        void Normalize();
    }
    public interface ICustomValidate
    {
        void AddValidationErrors(List<ValidationResult> results);
    }

 

定義Dto

    public class CreateTaskInput : IInput, IShouldNormalize, ICustomValidate
    {
        [StringLength(10, MinimumLength = 5)]
        public string Name { get; set; }

        public void Normalize()
        {
            Name = DateTime.Now.ToShortDateString() + "-task";
        }

        public void AddValidationErrors(List<ValidationResult> results)
        {
            if (Name == "xx")
            {
                results.Add(new ValidationResult("Task 名非法"));
            }
        }
    }

 

定義ApplicationService

    public interface ITaskAppService
    {
        void CreateTask(CreateTaskInput input);
    }

    public class TaskAppService : ITaskAppService
    {
        public void CreateTask(CreateTaskInput input)
        {
            Console.WriteLine("進入CreateTask方法:" + input.Name);
        }
    }

 

定義攔截器

    public class ValidateInterceptor : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            new MethodInvocationValidator(invocation.Arguments).Validate();
            invocation.Proceed();
        }
    }

 

驗證邏輯

    internal class MethodInvocationValidator
    {
        private readonly object[] _parameterValues;
        private readonly List<ValidationResult> _validationErrors;

        /// <summary>
        /// Creates a new <see cref="MethodInvocationValidator"/> instance.
        /// </summary>
        /// <param name="parameterValues">List of arguments those are used to call the <paramref name="method"/>.</param>
        public MethodInvocationValidator(object[] parameterValues)
        {
            _parameterValues = parameterValues;
            _validationErrors = new List<ValidationResult>();
        }

        public void Validate()
        {
            //basic validate
            for (var i = 0; i < _parameterValues.Length; i++)
            {
                ValidateObjectRecursively(_parameterValues[i]);
            }
       //throw exception
            if (_validationErrors.Any())
            {
                foreach (var validationResult in _validationErrors)
                {
                    Console.WriteLine("{0}:{1}", validationResult.MemberNames.FirstOrDefault(), validationResult.ErrorMessage);
                }
                throw new Exception("有參數異常");
            }
       //normalize foreach (var parameterValue in _parameterValues) { if (parameterValue is IShouldNormalize) { (parameterValue as IShouldNormalize).Normalize(); } } } private void ValidateObjectRecursively(object validatingObject) { var properties = TypeDescriptor.GetProperties(validatingObject).Cast<PropertyDescriptor>(); foreach (var property in properties) { var validationAttributes = property.Attributes.OfType<ValidationAttribute>().ToArray(); if (validationAttributes.IsNullOrEmpty()) { continue; } var validationContext = new ValidationContext(validatingObject) { DisplayName = property.Name, MemberName = property.Name }; foreach (var attribute in validationAttributes) { var result = attribute.GetValidationResult(property.GetValue(validatingObject), validationContext); if (result != null) { _validationErrors.Add(result); } } }         //custom validate if (validatingObject is ICustomValidate) { (validatingObject as ICustomValidate).AddValidationErrors(_validationErrors); } } }

  

執行

        static void Main(string[] args)
        {
            using (var container = new WindsorContainer())
            {
                container.Register(Component.For<IInterceptor, ValidateInterceptor>());//先注入攔截器
                container.Kernel.ComponentRegistered += Kernel_ComponentRegistered;
                container.Register(Component.For<ITaskAppService, TaskAppService>());
                var person = container.Resolve<ITaskAppService>();
                person.CreateTask(new CreateTaskInput() { Name = "123" });
            }
            Console.ReadKey();
        }

        static void Kernel_ComponentRegistered(string key, Castle.MicroKernel.IHandler handler)
        {
            handler.ComponentModel.Interceptors.Add(new InterceptorReference(typeof(ValidateInterceptor)));
        }

 

 

將name改成"12345"

 

本文地址:http://neverc.cnblogs.com/p/5267425.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM