ABP理論學習之驗證DTO


返回總目錄


本篇目錄

驗證介紹###

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM