ABP官方文档翻译 4.3 校验数据传输对象

时间:2021-02-16 19:54:39

校验数据传输对象

校验简介

  应用的输入首先应该被校验。输入可以是用户的也可以是其他应用的。在一个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";
}
}
}

返回主目录