文檔目錄
本節內容:
簡介
一個應用的輸入應當先要驗證,這個輸入可能來自用戶或另一個應用,在一個web應用裡,驗證通常實現兩次:在客戶端和在服務端,客戶端驗證是為了用戶體驗,最好是先檢查一個表單並向用戶顯示無效的輸入,但是服務端的驗證更具有決定性意義和必要性。
服務端驗證通常實現在應用服務或控制器(通常,所有服務從展現層獲取數據)。一個應用服務應該先檢查(驗證)輸入然後再使用它。ABP提供了一個基礎構造,自動驗證一個應用的如下三個的所有輸入:
如果需要禁用驗證,請查看“禁用驗證”小節。
使用數據注解
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接口。你同樣也可以實現它,執行額外的自定義驗證。如果你同時實現了這兩個接口,這兩個都會被調用。
禁用驗證
對於自動驗證類(查看“簡介”小節),你可以使用這些特性來控制驗證:
正常化
有時我們需要在驗證後,執行一個額外的操作來整理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"; } } }