zoukankan      html  css  js  c++  java
  • Attribute特性验证模型model

    数据验证我们往往分为前台验证和后台验证,而我们的后台验证每到一个方法中就要去验证一次,这样的代码想想都难以维护,这篇我们这篇文章就是为了解决这样的问题。用attribute 这个特性来解决这样的问题

    也将在这篇文章中告诉大家如何编写。

    调用方式:

      UserService applictionService = container.Resolve<UserService>();
                applictionService.AddUser(new User() { Name = "1",Age="bu gai " });
               
                Console.ReadLine();

    User 类:

        public class User
        {
            [StringLength(2,10)]
            public string Name { get; set; }
            [StringLength(5,10)]
            public string Age { get; set; }
        }

    结果:

    要做到上面的效果,笔者用的技术有:

    1.Castle 的依赖注入

    2.Castle 的动态代理技术

    3.Attribute特性的了解

    4.反射技术

     如果上面的技术你还不了解得话,你可以借助百度进行自行脑补

    在介绍细节之前,我们先来看看笔者的一个目录结构,然后在介绍每个类的细节

    1.ServiceInstaller:是这个test项目的核心依赖注入类

    2.User :是测试model

    3.IApplicationService:是服务的接口,在这里你们可以理解成mvc控制器接口

    4.OrderService,UserService是两个实现类,

    5.ServiceInterceptor:是动态代理类,也是实现这个功能的核心

    6.MethodInvocationValidator:是在方法执行之前进行实体model的验证

    7.ValidateAttribute:是验证的基类

    8.StringLength:是特性字符串长度的验证

    上面的有些类我就不一一进行讲解,主要讲解的就是ServiceInstaller,MethodInvocationValidator,ServerInterceptor

    ServiceInstaller代码:

     public void Install(IWindsorContainer container, IConfigurationStore store)
            {
                container.Register(Component.For<IWindsorContainer>().Instance(container).LifestyleSingleton());
    
                container.Register(Classes.FromThisAssembly().BasedOn<IApplicationService>().WithService.DefaultInterfaces());
    
                container.Register(Classes.FromThisAssembly().BasedOn<IInterceptor>().WithService.DefaultInterfaces());
    
                container.Register(Component.For<MethodInvocationValidator>().LifestyleTransient());
    
            }

      public static void Init(IWindsorContainer container)
            {
                container.Kernel.ComponentRegistered += Kernel_ComponentRegistered;
            }

            private static void Kernel_ComponentRegistered(string key, Castle.MicroKernel.IHandler handler)
            {
                if (typeof(IApplicationService).IsAssignableFrom(handler.ComponentModel.Implementation))
                {
                    handler.ComponentModel.Interceptors.Add(new Castle.Core.InterceptorReference(typeof(ServiceInterceptor.ServiceInterceptor)));
                }
            }

    第一注入就是对IWindsorContainer 自身的一个注入,因为其他要用到它,它是一个单例模式的。

    对也剩下的我想大家都懂,就是对这个应用程序集,继承自IApplicationService,IInterceptor的实体类进行注入,container.Kernel.ComponentRegistered是每注入一个组件就是执行这个事件,当我们注册的组件中继承了IApplication的实体类进行动态代理注入,

    ServerInterceptor 代码:

     public class ServiceInterceptor : IInterceptor
        {
            private readonly IWindsorContainer _container;
            public ServiceInterceptor(IWindsorContainer contaier)
            {
                _container = contaier;
            }
            public void Intercept(IInvocation invocation)
            {
                try
                {
                    var methodValidator = _container.Resolve<MethodInvocationValidator>();
                    methodValidator.Initialize(invocation.Method, invocation.Arguments);
                    methodValidator.Validator();
                    invocation.Proceed();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
               
            }
        }

     这个类就是每当调用service实体类时的方法时,就会触发这个Intercept方法, invovation参数包含了方法的信息和方法的参数数据,为我们反射提供基础

    MethodInvocationValidator 代码:

     //验证属性是否通过
            public void Validator()
            {
                for (int i=0;i<Method.GetParameters().Length;i++)
                {
                    var paraInfo = Method.GetParameters()[i];
                    foreach (PropertyInfo proInfo in  paraInfo.ParameterType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
                    {
                        foreach (CustomAttributeData attr in proInfo.CustomAttributes)
                        {
                           
                          var df= (ValidateAttribute) Activator.CreateInstance(attr.AttributeType, GetConstructorArguments(attr.ConstructorArguments));
                            var result= df.IsValidate(proInfo.GetValue(ParameterValues[i]));
                            if (!result)
                            {
                                ValidationErrors.Add(df.FormatMsgs(proInfo.Name));
                            }
    
                        }
                    }
                    if (ValidationErrors.Count > 0)
                    {
                        throw new Exception(ValidationErrors[0]);
                    }
                }
            }

    这个主要对调用方法的的参数进行反射,如果验证通过则调用原本的方法,不通过在一个新的异常,在外面捕获,并打印出来,

    最后:如果有什么不懂地方欢迎留言,dome链接 http://files.cnblogs.com/files/xuehaiyiye/TestNanHua.zip

  • 相关阅读:
    在springmvc中,什么是逻辑视图?什么是物理视图?
    docker2
    docker1
    HTTP Service 中篇
    HTTP Service 上篇
    Centos7 fstab盘符挂载硬盘导致重启系统失败解决办法
    vsphere网络
    LVS的工作原理认识
    数字转换
    对def函数的参数认识
  • 原文地址:https://www.cnblogs.com/xuehaiyiye/p/6213189.html
Copyright © 2011-2022 走看看