[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
[Architect] Abp 框架原理解析(4) Validation的更多相关文章
- [Architect] Abp 框架原理解析(5) UnitOfWork
本节目录 介绍 分析Abp源码 实现UOW 介绍 UOW(全称UnitOfWork)是指工作单元. 在Abp中,工作单元对于仓储和应用服务方法默认开启.并在一次请求中,共享同一个工作单元. 同时在Ab ...
- [Architect] Abp 框架原理解析(3) DynamicFilters
本节目录 介绍 定义Filter 设置Filter 这是Abp中多租户.软删除.激活\禁用等如此方便的原因 Install-Package EntityFramework.DynamicFilters ...
- [Architect] Abp 框架原理解析(2) EventBus
本节目录 原理介绍 Abp源码分析 代码实现 原理介绍 事件总线大致原理: (1) 在事件总线内部维护着一个事件与事件处理程序相映射的字典. (2) 利用反射,事件总线会将实现 ...
- [Architect] Abp 框架原理解析(1) Module
本节目录 Abp介绍 Abp源码分析 代码实现 Abp介绍 学习了一段时间的Abp,领略了一下前辈的架构.总结还是SOLID,降低耦合性. 虽然从架构上说甚至不依赖于DI框架,但实际上在基础框架中还是 ...
- [Architect] ABP(现代ASP.NET样板开发框架) 翻译
所有翻译文档,将上传word文档至GitHub 本节目录: 简介 代码示例 支持的功能 GitHub 简介 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目) ...
- ABP架构解析
ABP总体介绍 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...
- [置顶]
滴滴插件化VirtualAPK框架原理解析(二)之Service 管理
在前一篇博客滴滴插件化框架VirtualAPK原理解析(一)之插件Activity管理 中VirtualAPK是如何对Activity进行管理的,本篇博客,我们继续来学习这个框架,这次我们学习的是如何 ...
- ADB运行框架原理解析【转】
本文转载自:http://blog.csdn.net/wlwl0071986/article/details/50935496 一.adb守护进程的初始化 源码路径:~/system/core/adb ...
- Java并发Fork-Join框架原理解析
1.什么是Foirk/Join框架 Fork/Join框架是Java7提供用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架. 2.什么是并行流与顺 ...
随机推荐
- 高级屏幕空间反射: Screen Space Reflection (SSR)
自从CE3首倡SSR以来,发展至今,其质量与当年早已不能同日而语.不仅强调超越性的质量,而且强调超越性的性能.乘着周末有空撸了撸,以下是增强型实时SSR结果图.与我原来的SSR原始实现相比,新的增强型 ...
- IT技术团队行而有效的管理之道
在博客园看到的一份读书笔记,如果日后有机会去管理一个技术团队,那么下面这些经验可能会让你更好地实施工作. IT技术团队员工的特点 高学历,知识密集型,技术立身. 人际关系简单,摩擦大多数由技术产生,相 ...
- 《objective-c基础教程》学习笔记(十一)—— 类别
在编写面向对象程序的时候,我们经常想为现有的类添加一些新的行为.有些时候,我们可以创建这个类的子类.但是,如果我们用到工具集或者类库的时候,无法处理新建的子类.这时,Objective-C就给我们提供 ...
- algo_预备
章 C + +程序设计 大家好!现在我们将要开始一个穿越" 数据结构.算法和程序" 这个抽象世界的特殊旅程,以解决现实生活中的许多难题.在程序开发过程中通常需要做到如下两点:一是高 ...
- dsoframer控件学习小结(打开WORD,EXCEL等文件)
根据自己对dsoframer控件的学习,想把dsoframer控件进行简单的包装为C#的usercontrol,大体需要作如下:(创建windows的usercontrol的步骤就不再说了...)我们 ...
- C# MailMessage Attachment 中文名附件发邮件-Firefox中文显示正常,网页打开邮件附件中文名乱码
一.故事 首先通过CDO.Message来获取邮件EML相关数据:邮件标题.邮件内容.邮件附件.发件人.收件人.CC主要就这么几个,其次通过MailMessage来组织邮件通过Python来发送邮件! ...
- 让IE8支持HTML5及canvas功能!
微软出的IE9支持HTML5,但因为不支持XP系统,暂时我还用不了. 即使能用,现阶段如果开发HTML5页面,并考虑到兼容性问题的话,恐怕也得让自己的界面支持IE6-8吧. 首先,需要让IE支持HTM ...
- 查看、关闭linux自启动网络服务
1.查看 netstat --tulnp ..master smtp 服务 2.关闭 /etc/init.d/服务 stop 停止 : start 启动 chkconfig 服务 off 关闭 ...
- 使用IntelliJ IDEA 14和Maven创建java web项目
参考地址 http://www.cnblogs.com/jifeng/p/4658765.html
- A successful Git branching model
这个模型比较全,收藏一下,原文: http://nvie.com/posts/a-successful-git-branching-model/ 关于这个模型中的hotfix只适应最新的Release ...