校验数据传输对象

校验简介

  应用的输入首先应该被校验。输入可以是用户的也可以是其他应用的。在一个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 校验数据传输对象的更多相关文章

  1. ABP官方文档翻译 4.2 数据传输对象

    数据传输对象 DTOs的必要性 领域层的抽象 数据隐藏 序列化和懒加载问题 DTO转换和验证 示例 DTOs和实体间的自动映射 辅助接口和类 数据传输对象用来在应用层和展示层之间传输数据. 展示层调用 ...

  2. ABP官方文档翻译 4.1 应用服务

    应用服务 IApplicationService接口 ApplicationService类 CrudService和AsyncCrudAppService类 简单的CRUD应用服务示例 自定义CRU ...

  3. ABP官方文档翻译 0.0 ABP官方文档翻译目录

    一直想学习ABP,但囿于工作比较忙,没有合适的契机,当然最重要的还是自己懒.不知不觉从毕业到参加工作七年了,没留下点儿什么,总感觉很遗憾,所以今天终于卯足劲鼓起勇气开始写博客.有些事能做的很好,但要跟 ...

  4. ABP官方文档翻译 1.2 N层架构

    N层架构 介绍 ABP架构 其他(通用) 领域层 应用层 基础设施层 网络和展现层 其他 总结 介绍 应用程序代码库的分层架构是被广泛认可的可以减少程序复杂度.提高代码复用率的技术.为了实现分层架构, ...

  5. ABP官方文档翻译 6.4 导航

    导航 创建菜单 注册导航提供者 显示菜单 每一个网络应用都会有一些菜单用来在pages/screens之间导航.ABP提供了通用的基础设施来创建并显示菜单. 创建菜单 应用可以由不同的模块组成,每一个 ...

  6. ABP官方文档翻译 2.2 ABP会话

    ABP会话 介绍 关于IAbpSession 注入会话 会话属性 覆盖当前会话值 警告! 用户标示 介绍 如果应用需要登录的话,同样也需要知道当前用户可以执行哪些操作.ABP在展现层提供了会话对象,同 ...

  7. ABP官方文档翻译 3.2 值对象

    值对象 介绍 值对象基类 最佳实践 介绍 "展现领域描述性层面且没有概念性身份的对象称之为值对象."(Eric Evans). 和实体相反,实体有身份标示(Id),值对象没有身份标 ...

  8. ABP官方文档翻译 2.7 对象到对象的映射

    对象到对象的映射 介绍 IObjectMapper接口 AutoMapper集成 安装 创建映射 自动映射属性 自定义映射 MapTo扩展方法 单元测试 预定义映射 LocalizeableStrin ...

  9. 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 ...

随机推荐

  1. js onclick传递 对象

    在html onclick中如果参数直接传递一个参数js会报错. 如果想要onclick传递参数需要这么做: var user = {id:1, name:'hk'}; var ele = '< ...

  2. Netty5序章之BIO NIO AIO演变

    Netty5序章之BIO NIO AIO演变 Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠的网络服务器和客户端程序.Netty简化了网络程序的开发,是很多框架和公司都在使 ...

  3. 如何开发由Create-React-App 引导的应用(三)

    此文章是翻译How to develop apps bootstrapped with Create React App 官方文档 系列文章 如何开发由Create-React-App 引导的应用 如 ...

  4. mysql数据库创建、删除数据库

    一.创建数据库(默认字符集和排序规则)     (1)创建数据库 mysql> CREATE DATABASE my_db1; Query OK, 1 row affected (0.00 se ...

  5. 分享给有需要的你,精选了10套web开发免费视频教程~~

    在这里给大家精选百度传课里的一些比较好的视频教程,比较适合新手们,有需要的可以收藏着学习!!  蓝鸥微信小程序全方位深度解析 链接:http://www.chuanke.com/v4702151-19 ...

  6. 织梦首页、列表页调用文章body内容的两种方法

    http://blog.csdn.net/langyu1021/article/details/52261411 关于首页.列表页调用文章body内容的两种方法,具体方法如下: 第一种方法: {ded ...

  7. Spring整合Struts的两种方式介绍

    1 使用Spring托管Struts Action 该种方式就是将Struts Action也视为一种Bean交给Spring来进行托管,使用时Struts的配置文件中配置的Action的classs ...

  8. JavaScript获取当前url根目录(路径)

    jsp: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8&q ...

  9. svn checkout The XML response contains invalid XML

    svn checkout 报错:The XML response contains invalid XML 待解决? ---目前没有找到好的解决方法,svn数据库中存的log入手应该可以,有时间再去看 ...

  10. sql 时间转换问题 from_unixtime() UNIX_TIMESTAMP()

    http://blog.csdn.net/test_soy/article/details/50328367 from_unixtime()是MySQL里的时间函数 date为需要处理的参数(该参数是 ...