ABP官方文档翻译 4.3 校验数据传输对象
校验数据传输对象
校验简介
应用的输入首先应该被校验。输入可以是用户的也可以是其他应用的。在一个web应用中,校验通常实现两次:客户端和服务端。客户端校验是为了用户体验。最好现在客户端校验表单并显示给用户无效的字段。但是,服务端校验要更紧要且不可避免的。
服务端校验一般在应用服务或控制器实现(通常,所有的服务从展示层获得数据)。应用服务方法应该先检查(校验)输入再使用。ABP提供了良好的基础设施来自动校验应用的输入:
- 所有的应用服务方法
- 所有的ASP.NET Core MVC控制器方法
- 所有的ASP.NET MVC和Web API控制器方法
参见禁用校验部分来禁用校验,如果有需要的话。
使用数据标注
ABP支持数据标注特性。假定我们开发了一个Task应用服务用来创建一个Task,按如下所示获取输入:
public class CreateTaskInput
{
public int? AssignedPersonId { get; set; } [Required]
public string Description { get; set; }
}
这里,Description属性标记为Required。AssignedPersonId是可选的。在System.ComponentModel.DataAnnotations命名空间里有许多特性(如MaxLength,MinLength,RegularExpression...)。参见Task应用服务的实现:
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检查input是否为null,如果为的话则抛出AbpValidationException。所以,你不用编写null-check代码(守护语句)。如果任何输入属性无效,它都会抛出AbpValidationException。
这种机制和ASP.NET MVC的校验相似,但是注意应用服务不是继承自Controller,它是一个普通的类并且可以在web应用外使用。
自定义校验
如果数据标注不满足你的案例,你可以按如下方式实现ICustomValidate接口:
public class CreateTaskInput : ICustomValidate
{
public int? AssignedPersonId { get; set; } public bool SendEmailToAssignedPerson { get; set; } [Required]
public string Description { get; set; } public void AddValidationErrors(CustomValidatationContext context)
{
if (SendEmailToAssignedPerson && (!AssignedPersonId.HasValue || AssignedPersonId.Value <= ))
{
context.Results.Add(new ValidationResult("AssignedPersonId must be set if SendEmailToAssignedPerson is true!"));
}
}
}
ICustomValidate接口声明了AddValidationErrors方法。如果有校验错误,我们必须添加ValidationResult对象到context.Results列表。你可以使用context.IoCResolver来解决依赖关系,如果在校验过程中需要的话。
除了ICustomValidate,ABP也提供了支持.NET的标准IValidatableObject接口。你也可以实现它来执行其他的自定义校验。如果你同时实现了这两个接口,它们将会都被调用。
禁用校验
对于自动校验的类(参见介绍部分),你可以使用这些属性控制校验:
- DisableValidation特性可以用于classes,方法或DTOs的属性来禁用校验。
- EnableValidation特性只能用来给方法启用校验,如果它被包含的类禁用的话。
标准化
我们可能在校验之后需要执行一些操作来安排DTO参数。ABP定义了IShouldNormalize接口,它为此有一个Normalize方法。如果你实现了这个接口,Normalize方法会在校验(仅在方法调用之前)之后调用。假定我们的DTO获取一个排序方向。如果它没被提供,我们希望设置一个默认的排序:
public class GetTasksInput : IShouldNormalize
{
public string Sorting { get; set; } public void Normalize()
{
if (string.IsNullOrWhiteSpace(Sorting))
{
Sorting = "Name ASC";
}
}
}
ABP官方文档翻译 4.3 校验数据传输对象的更多相关文章
- ABP官方文档翻译 4.2 数据传输对象
数据传输对象 DTOs的必要性 领域层的抽象 数据隐藏 序列化和懒加载问题 DTO转换和验证 示例 DTOs和实体间的自动映射 辅助接口和类 数据传输对象用来在应用层和展示层之间传输数据. 展示层调用 ...
- ABP官方文档翻译 4.1 应用服务
应用服务 IApplicationService接口 ApplicationService类 CrudService和AsyncCrudAppService类 简单的CRUD应用服务示例 自定义CRU ...
- ABP官方文档翻译 0.0 ABP官方文档翻译目录
一直想学习ABP,但囿于工作比较忙,没有合适的契机,当然最重要的还是自己懒.不知不觉从毕业到参加工作七年了,没留下点儿什么,总感觉很遗憾,所以今天终于卯足劲鼓起勇气开始写博客.有些事能做的很好,但要跟 ...
- ABP官方文档翻译 1.2 N层架构
N层架构 介绍 ABP架构 其他(通用) 领域层 应用层 基础设施层 网络和展现层 其他 总结 介绍 应用程序代码库的分层架构是被广泛认可的可以减少程序复杂度.提高代码复用率的技术.为了实现分层架构, ...
- ABP官方文档翻译 6.4 导航
导航 创建菜单 注册导航提供者 显示菜单 每一个网络应用都会有一些菜单用来在pages/screens之间导航.ABP提供了通用的基础设施来创建并显示菜单. 创建菜单 应用可以由不同的模块组成,每一个 ...
- ABP官方文档翻译 2.2 ABP会话
ABP会话 介绍 关于IAbpSession 注入会话 会话属性 覆盖当前会话值 警告! 用户标示 介绍 如果应用需要登录的话,同样也需要知道当前用户可以执行哪些操作.ABP在展现层提供了会话对象,同 ...
- ABP官方文档翻译 3.2 值对象
值对象 介绍 值对象基类 最佳实践 介绍 "展现领域描述性层面且没有概念性身份的对象称之为值对象."(Eric Evans). 和实体相反,实体有身份标示(Id),值对象没有身份标 ...
- ABP官方文档翻译 2.7 对象到对象的映射
对象到对象的映射 介绍 IObjectMapper接口 AutoMapper集成 安装 创建映射 自动映射属性 自定义映射 MapTo扩展方法 单元测试 预定义映射 LocalizeableStrin ...
- ABP官方文档翻译 10.1 ABP Nuget包
ABP Nuget包 Packages Abp Abp.AspNetCore Abp.Web.Common Abp.Web Abp.Web.Mvc Abp.Web.Api Abp.Web.Api.OD ...
随机推荐
- HDU2824-The Euler function-筛选法求欧拉函数+求和
欧拉函数: φ(n)=n*(1-1/p1)(1-1/p2)....(1-1/pk),其中p1.p2-pk为n的所有素因子.比如:φ(12)=12*(1-1/2)(1-1/3)=4.可以用类似求素数的筛 ...
- codeforces Gym 101063 C
二进制转十进制 然后按位比较 传送门 http://codeforces.com/gym/101063 #include <cstdio> #include <cmath> # ...
- Logger之Logger.getLogger(CLass)技巧代替system.out.print
---恢复内容开始--- 尊重原创:http://www.cnblogs.com/zxf330301/p/5876117.html 之前一直在使用System.out.println()来调试.但是用 ...
- spring如何控制事务
Spring 的事务,可以说是 Spring AOP 的一种实现. AOP面向切面编程,即在不修改源代码的情况下,对原有功能进行扩展,通过代理类来对具体类进行操作. spring是一个容器,通过spr ...
- fireasy 使用篇 - 简介
一.Fireasy 简介 Fireasy是一套基于.Net Framework应用开发组件,其主旨思想为“让开发变为更简单”,其义为,使用尽可能少的组件,实现你所需的功能.Fireasy几乎覆盖了开发 ...
- (一)surging 微服务框架使用系列之surging 的准备工作rabbitmq安装
(1)下载erlang: http://www.erlang.org/download/otp_win64_17.3.exe 并安装 (2)下载RabbitMQ: http://www.rabbitm ...
- IO代码记忆
FileWriter fw = new FileWriter("hello.txt"); String s = "hello world"; fw.write( ...
- redis安装、测试&集群的搭建&踩过的坑
1 redis的安装 1.1 安装redis 版本说明 本教程使用redis3.0版本.3.0版本主要增加了redis集群功能. 安装的前提条件: 需要安装gcc:yum install gcc- ...
- centos利用yum安装卸载软件常用命令
来自:http://tech.v01.cn/Linuxchangjianwenti/changyongruanjiananzhuangyucao/2012/0119/70.html 一.使用yum安装 ...
- Eclipse报错An internal error occurred during: "J2EE Component Mapping Update". java.lang.NullPointerException
Eclipse每次打开.java文件时,报错信息如下: An internal error occurred during: "J2EE Component Mapping Update&q ...