本篇目錄
驗證介紹###
首先應該驗證應用的輸入。用戶或者其它應用都可以向該應用發送輸入。在一個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";
}
}
}