ABP理论学习之验证DTO
本篇目录
验证介绍###
首先应该验证应用的输入。用户或者其它应用都可以向该应用发送输入。在一个web应用中,验证通常要实现两次:在客户端和服务器端。客户端的验证大多数情况下是为用户体验而实现的。在客户端最好先检查一下表单,并向用户展示不合法的字段。但是服务端的验证更关键且不可避免。
服务端的验证通常实现在应用服务层。应用服务方法应首先检查(验证)输入然后再使用它。ABP提供了一个很好的基础设施来验证应用服务方法的输入。
应用服务方法接收一个DTO(数据传输对象)作为输入。ABP有一个IValidate接口,凡是实现了该接口的DTO都可以自动地进行验证。因为IInputDto继承了IValidate,因此只要为输入DTOs实现IInputDto就可以确保验证了。
使用数据注解###
ABP支持数据注解特性。假设我们要开发一个任务(Task)应用服务,该服务用于创建一个任务,它的输入参数类型如下所示:
public class CreateTaskInput : IInputDto
{
public int? AssignedPersonId { get; set; }
[Required]
public string Description { get; set; }
}
这里,Description属性标记为 Required。AssignedPersonId是可选的。在 System.ComponentModel.DataAnnotations命名空间中也有很多特性(如MaxLength,MinLength,RegularExpression等等)。来看一下任务应用服务的实现:
public class TaskAppService : ITaskAppService
{
private readonly ITaskRepository _taskRepository;
private readonly IPersonRepository _personRepository;
public TaskAppService(ITaskRepository taskRepository, IPersonRepository personRepository)
{
_taskRepository = taskRepository;
_personRepository = personRepository;
}
public void CreateTask(CreateTaskInput input)
{
var task = new Task { Description = input.Description };
if (input.AssignedPersonId.HasValue)
{
task.AssignedPerson = _personRepository.Load(input.AssignedPersonId.Value);
}
_taskRepository.Insert(task);
}
}
正如你所看到的,这里没写验证代码,因为ABP会自动进行验证。ABP也会检查输入是否为null。如果为null,就会抛出 AbpValidationException。因此,你也不用写检测null的代码(保卫语句)。如果输入的属性有任何一个是非法的,那么就会抛出相同的异常。
该机制和ASP.NET MVC的验证相似,但是注意的是应用服务类不是派生自Controller,而只是一个纯粹的类并且在web应用之外工作。
自定义验证###
如果数据注解还不能满足你的情况,那么你可以实现ICustomValidate接口,如下所示:
public class CreateTaskInput : IInputDto, ICustomValidate
{
public int? AssignedPersonId { get; set; }
public bool SendEmailToAssignedPerson { get; set; }
[Required]
public string Description { get; set; }
public void AddValidationErrors(List<ValidationResult> results)
{
if (SendEmailToAssignedPerson && (!AssignedPersonId.HasValue || AssignedPersonId.Value <= 0))
{
results.Add(new ValidationResult("AssignedPersonId must be set if SendEmailToAssignedPerson is true!"));
}
}
}
ICustomValidate接口声明了要实现的AddValidationErrors方法。这里,我们有一个 SendEmailToAssignedPerson属性。如果它的值是true, 而且没有提供AssignedPersonId或值是负数,那么我们就认为这里发生了验证错误,我们必须将ValidationResult对象添加到 results集合中。
标准化###
我们可能在验证之后执行一个额外的操作来排列DTO参数。ABP定义了IShouldNormalize接口, 该接口中定义了Normalize方法来达到排列DTO参数的目的。如果你实现了该接口,那么就应该在验证之后(方法调用之前)调用Normalize方法。假如我们的DTO要有一个排序(Sorting)方向,如果没有提供的话,我们就要设置一个默认值:
public class GetTasksInput : IInputDto, IShouldNormalize
{
public string Sorting { get; set; }
public void Normalize()
{
if (string.IsNullOrWhiteSpace(Sorting))
{
Sorting = "Name ASC";
}
}
}
ABP理论学习之验证DTO的更多相关文章
- ABP理论学习之数据传输对象(DTO)
返回总目录 本篇目录 为何需要DTO 领域层抽象 数据隐藏 序列化和懒加载问题 DTO惯例和验证 DTO和实体的自动映射 使用特性和扩展方法进行映射 帮助接口 DTO用于应用层和 展现层间的数据传输. ...
- ABP(现代ASP.NET样板开发框架)系列之18、ABP应用层——权限验证
点这里进入ABP系列文章总目录 ABP(现代ASP.NET样板开发框架)系列之18.ABP应用层——权限验证 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目 ...
- ABP理论学习之Javascript API(理论完结篇)
返回总目录 本篇目录 Ajax Notification Message UI block和busy 事件总线 Logging 其他工具功能 说在前面的话 不知不觉,我们送走了2015,同时迎来了20 ...
- ABP应用层——权限验证
ABP应用层——权限验证 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ABP的官方网站:http://www.aspnetboilerpla ...
- ABP理论学习之N层架构
返回总目录 自从写这个系列博客之后,发现很多园友还是希望有个直接运行的demo,其实在github上就有官方的demo,我直接把这demo的链接放到这里吧,另外,我分析,这些找不到demo的同学,很可 ...
- ABP理论学习之应用服务
返回总目录 本篇目录 IApplicationService接口 ApplicationService类 工作单元 数据库连接和事务管理 自动保存更改 更多 应用服务的生命周期 应用服务用于将领域逻辑 ...
- ABP理论学习之开篇介绍
返回总目录 为了和2016年春节赛跑,完成该系列博客,我牺牲了今天中午的时间来完成该系列的第一篇----开篇介绍.开篇介绍嘛,读过大学教材的同学都知道,这玩意总是那么无聊,跟考试没关系,干脆直接跳过, ...
- ABP理论学习之领域服务
返回总目录 本篇目录 介绍 IDomainService接口和DomainService类 样例 创建一个接口 服务实现 调用应用服务 一些讨论 何不只使用应用服务 如何强制使用领域服务 介绍 领域服 ...
- ABP理论学习之异常处理
返回总目录 本篇目录 介绍 开启错误处理 非Ajax请求 展示异常信息 UserFriendlyException Error模型 Ajax请求 异常事件 介绍 在一个web应用中,异常通常是在MVC ...
随机推荐
- Python 创建本地服务器环境生成二维码
一. 需求 公司要做一个H5手机端适配页面,因技术问题所以H5是外包的,每次前端给我们源码,我们把源码传到服务器让其他人访问看是否存在bug,这个不是很麻烦吗?有人说,可以让前端在他们的服务器上先托管 ...
- npm设计代理
概述: 在需要代理才能上网的环境下,需要给npm设置代理才能完成安装 npm install 代理设置: 直接使用npm install会报错,如下: npm ERR! node v6.7.0 np ...
- myeclipse一直卡在loading workbench解决方法
删除工作空间下.metadata中的org.eclipse.ui.workbench org.eclipse.ui.workbench.texteditor
- Power服务器中KVM克隆新虚拟机
查看当前所有虚拟机:virsh list --all 克隆新虚拟机:virt-clone -o guest01 -n guest02 -f /var/lib/libvirt/images/guest ...
- Go语言 模板的使用(一)
使用Parse package main import ( "html/template" "net/http" ) func SayHello(w http. ...
- python遍历一个网段的ip地址
def ip2num(ip):#ip to int num lp = [int(x) for x in ip.split('.')] return lp[0] << 24 | lp[1] ...
- WebGL入门教程(五)-webgl纹理
前面文章: WebGL入门教程(一)-初识webgl WebGL入门教程(二)-webgl绘制三角形 WebGL入门教程(三)-webgl动画 WebGL入门教程(四)-webgl颜色 这里就需要用到 ...
- 《UML大战需求分析》阅读随笔(四)
状态机图(State Machine Diagram),状态机图是通过描述某事物状态的改变来展现流程的.一般适用于流程围绕某个事物展开,例如请假的流程就围绕请假条的展开.语法,开始于结束符号,实心圆表 ...
- xml_TO_object
一般对于开发人员拿到的xml文件都是配置文件,所以对于我们来说,最主要要做的事情是将xml的内容封装成对象. 下面展示代码 package javaDom4j; import java.util.Ar ...
- 多线程之信号量(By C++)
信号量在多线程中,主要是用于线程的同步或者限制线程运行的数量. 所谓同步,当流程1运行在线程1中,流程2运行在线程2中,流程2必须在流程1结束之后才能开始执行.你会怎么做,所有就需要给出一个流程1结束 ...