首页 > 代码库 > <<ABP框架>> 验证数据传输对象

<<ABP框架>> 验证数据传输对象

文档目录

 

本节内容:

  • 简介
  • 使用数据注解
  • 自定义验证
  • 禁用验证
  • 正常化

 

简介

一个应用的输入应当先要验证,这个输入可能来自用户或另一个应用,在一个web应用里,验证通常实现两次:在客户端和在服务端,客户端验证是为了用户体验,最好是先检查一个表单并向用户显示无效的输入,但是服务端的验证更具有决定性意义和必要性。

服务端验证通常实现在应用服务或控制器(通常,所有服务从展现层获取数据)。一个应用服务应该先检查(验证)输入然后再使用它。ABP提供了一个基础构造,自动验证一个应用的如下三个的所有输入:

  • 所有应用服务方法。
  • 所有Asp.net Core Mvc控制器的Action。
  • 所有Asp.net Mvc和Web Api控制器的Action。

如果需要禁用验证,请查看“禁用验证”小节。

 

使用数据注解

ABP支持数据注解特性,假设我们正在开发一个Task应用服务,它用来创建一个Task并需要一个输入,如下所示:

public class CreateTaskInput{    public int? AssignedPersonId { get; set; }    [Required]    public string Description { get; set; }}

这里的Description属性被标记为Required,AssingedPersonId是可选的,在System.ComponentModel.DataAnnotations命名空间里,还有很多特性(如MaxLength、MinLenggth、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会验证如果输入为null,就抛出AbpValidationException,所以你不需要写null检查。如果输入的任何属性是无效的,它也会抛出AbpValidationException。

这种机制类似于Asp.net Mvc的验证,但请注意一个应用服务类不是从控制器继承过来,它就是一个单纯的类,甚至可以在一个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 <= 0))        {            context.Results.Add(new ValidationResult("AssignedPersonId must be set if SendEmailToAssignedPerson is true!"));        }    }}

ICustomValidate接口定义了AddValidationErrors方法,如果有验证错误,我们必须添加ValidationResult对象到context.Results列表。在验证进度里,如果有需要,你可以用context.IocResolver来解析依赖。

除了ICustomValidate,ABP也支持IValidatableObject接口。你同样也可以实现它,执行额外的自定义验证。如果你同时实现了这两个接口,这两个都会被调用。

 

禁用验证

对于自动验证类(查看“简介”小节),你可以使用这些特性来控制验证:

  • DisableValidation特性:可用在DTO的类,方法或属性上来禁用验证。
  • EnableValidation特性:在一个被禁用验证的类里,可以在方法上使用这个特性让当前方法的输入验证可用。

 

正常化

有时我们需要在验证后,执行一个额外的操作来整理DTO参数。ABP定义了IShouldNormailize接口,包含Normalize方法,如果你实现了这个接口,Normalize方法在验证后(在方法被调用前)被调用。假设我们需要从DTO里取得排序方向(升序、降序),如果未提供,我们想设置一个默认值:

public class GetTasksInput : IShouldNormalize{    public string Sorting { get; set; }    public void Normalize()    {        if (string.IsNullOrWhiteSpace(Sorting))        {            Sorting = "Name ASC";        }    }}

 

<<ABP框架>> 验证数据传输对象