ABP應用層——參數有效性驗證


ABP應用層——參數有效性驗證

基於DDD的現代ASP.NET開發框架--ABP系列之17、ABP應用層——參數有效性驗證

 

ABP是“ASP.NET Boilerplate Project (ASP.NET樣板項目)”的簡稱。

ABP的官方網站http://www.aspnetboilerplate.com

ABP在Github上的開源項目https://github.com/aspnetboilerplate

 


 

應用程序的輸入數據首先應該被檢驗是否有效。輸入的數據能被用戶或其他應用程序提交。在Web應用中,通常進行2次數據有效性檢驗:包括客戶端檢驗和服務端檢驗。客戶端的檢驗主要是使用戶有一個好的用戶體驗。 首先最好是在客戶端檢驗其表單輸入的有效性並且展示給客戶端的那些字段輸入是無效的。但是,服務器端的校驗是更關鍵和不可缺失的(不要只做客戶端檢驗而不做服務器端檢驗)。

服務器端的檢驗通常是被應用服務(層)執行,應用服務(層)中的方法首先檢驗數據的有效性,然后才使用這些通過驗證的數據。ABP的基礎設施提供了自動檢驗輸入數據有效性的方法。

應用服務(層)方法得到一個數據傳輸對象(DTO)作為輸入。ABP有一個IValidate的接口,DTO通過實現這個接口能夠檢驗數據的有效性。由於IInputDto擴展自IValidate,所以你可以直接實現IInputDto 接口來對數據傳輸對象(DTO)檢驗其有效性。

使用數據注解

ABP提供數據注解的特性。假設我們正在開發一個創建任務的應用服務並且得到了一個輸入,請看下面示例:

復制代碼
public class CreateTaskInput : IInputDto
{
    public int? AssignedPersonId { get; set; }

    [Required]
    public string Description { get; set; }
}
復制代碼

在這里,Description 屬性被標記為 Required。AssignedPersonId 是可選的。在 System.ComponentModel.DataAnnotations 命名空間中,還有很多這樣的特性 ( 例如: MaxLength, MinLength, RegularExpression 等等 )。

在System.ComponentModel.DataAnnotations 命名空間中,請看Task application service 的實現

復制代碼
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);
    }
}
復制代碼

正如你所看到的,這里沒有寫任何的數據驗證性代碼(指對Description屬性的驗證)因為ABP會自動去檢驗數據的有效性。ABP也會檢驗輸入數據是否為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 的屬性。如果該屬性是真,AssignedPersonId 屬性會被檢驗是否有效,否則該屬性可以為空。如果有驗證錯誤,我們必須添加把這些驗證結果添加到結果集合中。(就是將ValidationResult 添加到results)

設置缺省值

在檢驗數據有效性后,我們需要執行一個額外的操作來整理DTO參數。ABP定義了一個IShouldNormalize接口,這個接口聲明了一個 Normalize的方法。如果你實現了這個接口,在檢驗數據有效性后,Normalize方法會被調用。假設我們的DTO需要一個排序方向的數據。如果這個Sorting屬性沒有被提供數據,那么在Normalize我們可以給Sorting設置一個缺省值。

復制代碼
public class GetTasksInput : IInputDto, IShouldNormalize
{
    public string Sorting { get; set; }

    public void Normalize()
    {
        if (string.IsNullOrWhiteSpace(Sorting))
        {
            Sorting = "Name ASC";
        }
    }
}
復制代碼

 


希望更多國內的架構師能關注到ABP這個項目,也許這其中有能幫助到您的地方,也許有您的參與,這個項目可以發展得更好。

歡迎加ABP架構設計交流QQ群:134710707

ABP架構設計交流群

 

點這里進入ABP系列文章總目錄


免責聲明!

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



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