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

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

调用方式:

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

User 类:

    public class User
{
[StringLength(,)]
public string Name { get; set; }
[StringLength(,)]
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=;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 > )
{
throw new Exception(ValidationErrors[]);
}
}
}

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

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

Attribute特性验证模型model的更多相关文章

  1. Net中Attribute特性的高级使用及自定义验证实现

    好久没写博客了,今天在百忙之中抽空来写篇文章,记录一下最近深入学习Attribute特性的笔记及心得.~~ 一.什么是特性? 特性(Attribute)是用于在运行时传递程序中各种元素(比如类.方法. ...

  2. 【再探backbone 01】模型-Model

    前言 点保存时候不注意发出来了,有需要的朋友将就看吧,还在更新...... 几个月前学习了一下backbone,这段时间也用了下,感觉之前对backbone的学习很是基础,前几天有个园友问我如何将路由 ...

  3. MVC的验证(模型注解和非侵入式脚本的结合使用) .Net中初探Redis .net通过代码发送邮件 Log4net (Log for .net) 使用GDI技术创建ASP.NET验证码 Razor模板引擎 (RazorEngine) .Net程序员应该掌握的正则表达式

    MVC的验证(模型注解和非侵入式脚本的结合使用)   @HtmlHrlper方式创建的标签,会自动生成一些属性,其中一些属性就是关于验证 如图示例: 模型注解 通过模型注解后,MVC的验证,包括前台客 ...

  4. ThinkPHP 模型(Model)命名规范

    一个小问题搞了好久:如果数据库的表名中有下划线,那么在用thinkphp做自动完成时注意Model类的命名要变成驼峰法,文件名和类名都要变.( 另外注意:只有使用create方法创建数据时才能调用到自 ...

  5. sencha touch之模型(model)

    模型的实例相当于数据库中表的一条记录. 一般模型在\app\model下创建,而且必须遵守类的命名规则,也就是可以根据类名找到模型的定义文件. 所有模型类都要从Ext.data.Model或Ext.d ...

  6. 利用libsvm-mat建立分类模型model参数解密[zz from faruto]

    本帖子主要就是讲解利用libsvm-mat工具箱建立分类(回归模型)后,得到的模型model里面参数的意义都是神马?以及如果通过model得到相应模型的表达式,这里主要以分类问题为例子. 测试数据使用 ...

  7. 【在 Nervos CKB 上做开发】Nervos CKB 脚本编程简介[1]:验证模型

    CKB 脚本编程简介[1]: 验证模型 本文作者:Xuejie 原文链接:Introduction to CKB Script Programming 1: Validation Model 本文译者 ...

  8. .NET进阶篇03-Reflection反射、Attribute特性

    知识需要不断积累.总结和沉淀,思考和写作是成长的催化剂 内容目录 一.概述二.反射1.反射使用2.创建对象3.调用方法4.字段属性三.特性四.总结 一.概述 反射其实无处不在,我们用VS进行调试时候, ...

  9. ASP.NET MVC在布局页上使用模型(model)

    看到这标题有点怪,一般情况之下,我们很容易在视图与部分视图中使用模型(model),但是如果想在布局页_Layout.cshtml页中使用模型(model),按照普通方式也许没有达到预期的效果,在实现 ...

随机推荐

  1. Android 通过 Intent 传递类对象

    Android中Intent传递类对象提供了两种方式一种是 通过实现Serializable接口传递对象,一种是通过实现Parcelable接口传递对象. 要求被传递的对象必须实现上述2种接口中的一种 ...

  2. Android开发之音乐播放器的实现

    Android音乐播放器 使用到Android的Actiivity和Service组件 播放音频的代码应该运行在服务中,定义一个播放服务MusicService,服务里定义play.stop.paus ...

  3. js匿名函数

    <script type="text/javascript"> $(function () { $("#btn").mousedown(functi ...

  4. BZOJ2542: [Ctsc2001]终极情报网

    题解: 乘积最小只需要取对数.然后反向边就变成1/c,而不是-c了. 精度问题搞得我已经我想说什么了... 贴一份网上的pascal 代码: type ss=record x,y,c,r,next:l ...

  5. Terrocotta - 基于JVM的Java应用集群解决方案

    前言 越来越多的企业关键应用都必须采用集群技术,实现负载均衡(Load Balancing).容错(Fault Tolerance)和灾难恢复(Failover).以达到系统可用性(High Avai ...

  6. Spring编程风格

    给自己使用的无需定义接口:即一个模块内部的都是封装的,定义接口并不会得到很多好处,变过几次实现?? “优先面向接口编程,而非实现” 不是必须,是优先: 给朋友(第三方)使用的定义接口:即要公开的功能, ...

  7. java的四舍五入算法

    粗力度的四舍五入为整数 package math; public class MathRoundTest { /** * Math类中提供了三个与取整有关的方法:ceil,floor,round, * ...

  8. Android开发优化宝典

    I. 网络相关 http头信息带Cache-Control域 确定缓存过期时间 防止重复请求 直接用IP直连,不用域名,策略性跟新本地IP列表. – DNS解析过程耗时在百毫秒左右,并且还有可能存在D ...

  9. HDU 4968 Improving the GPA

    Improving the GPA Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  10. 【管理工具】Kerberos简单应用

    Kerberos这一名词来源于希腊神话“三个头的狗——地狱之门守护者”系统设计上采用客户端/服务器结构与DES加密技术,并且能够进行相互认证,即客户端和服务器端均可对对方进行身份认证.可以用于防止窃听 ...