Server 在接收 Client 的資料時,Model 內的參數都會有各自的規則,例如:不得為空、只能為數字、最多100字、要是Email格式…等,驗證的規則可以在 Client 就規範好或者是傳回 Server 時檢查,而在 Server 時資料驗證就是資料格式的最後一道防線,這時會不會有個疑問?那我通通在 Server 驗證就好啦~問什麼需要 Client 與 Server 同時驗證呢?其實兩種驗證是有不一樣的效果的:

(1) Client 驗證:傳回 Server 前先驗證會有效減少 Request 的數量,不需要到呼叫 API 後回傳資訊才知道資料錯誤,能有效減少Server與Client之間的來回的時間成本。

(2) Server 驗證:在 Server 收到資料後驗證,能作為資料的最後一道防線,以防資料進入資料庫時錯誤,能有效減少 Server 與 DB 之間來回的時間成本。

那本篇說明的內容會以 Server 驗證為主,在介紹本篇主軸 FluentValidation前,我們先來認識 .NET 提供的一些驗證方法:

(1) [Required]:驗證欄位不是 null。

(2) [Phone]:驗證屬性具有電話號碼格式。

(3) [EmailAddress]:驗證屬性具有電子郵件格式。

(4) [Url]:驗證屬性是否具有 URL 格式。

(5) [StringLength]:驗證字串屬性值不超過指定的長度限制。

(6) [Range]:驗證屬性值是否落在指定的範圍內。

(7) [CreditCard]:驗證屬性是否具有信用卡格式。

(8) [Compare]:驗證模型中的兩個屬性是否相符。

(9) [RegularExpression]:驗證屬性值是否符合指定的正則運算式。

這幾是其中一角的驗證規則,詳細的驗證規則放在底下的參考2,有需要可以自行參閱。現在我們來實作看看 .NET 的驗證規則,先建立一個 Model 放入想要驗證的參數(我們這邊以登入 Model 為例),我們為帳號 Account 設立驗證規則為不得為空、帳號為信箱,密碼 Passwrod 設立驗證規則為不得為空、只能為8位數字,這時我們可以在 LoginDto 中放入上述條件,並用啟用 Swagger 後呼叫 LoginUser 會得到以下結果(圖一)。

圖一 Swagger

回傳結果竟然是

400 "Request cannot be processed. Please contact a support."

不是應該人性化提醒參數上有哪些錯誤嗎?別緊張,我們在 Startup.cs 中的 ConfigureServices 需要加上一段 AddMvc(),用來攔截驗證的錯誤資訊並且針對錯誤訊息去做處理,再次啟用 Swagger 後呼叫 LoginUser 就可以看到當我們的參數沒有符合驗證時,會跑出錯誤提醒(圖二)。

圖二 Swagger

那 .NET 原生的驗證方法就很好用了,為什麼我們還要介紹 FluentValidation 呢?在上面使用 .NET 原生的驗證方法時,我們可以看到驗證邏輯與 Model 會在同一個檔案下,使用 FluentValidation 就是希望將驗證邏輯與 Model 分開以方便進行管理,讓專案架構更簡單明瞭,FluentValidation 的驗證不同於 .NET 的方式,會獨立建立Validator,將驗證邏輯寫在 Validator 內,而需要驗證時透過 Validator來驗證。請先在 NuGet 裡下載組件 FluentValidation 與 FluentValidation.AspNetCore(圖三),並且在Startup.cs 內的 ConfigureServices 中註冊 FluentValidation。

圖三 NuGet

註冊完後,我們建立一個 UserValidator 放入剛剛我們制定好的驗證規則(帳號 Account 設立驗證規則為不得為空、帳號為信箱,密碼 Passwrod 設立驗證規則為不得為空、只能為8位數字),再次啟用 Swagger 後呼叫 LoginUser 就可以看到當我們的參數沒有符合驗證時,會跑出錯誤提醒(圖四)。

圖四 Swagger

FluentValidation 和 .NET 一樣有許多種驗證規則,詳細驗證規則舉幾個常用的例子放在下方程式碼內,如需要更詳細的請參閱底下的參考4。

FluentValidation 有個要特別注意的地方,如果 Model 內包含其他子 Model 時,Validator 就需要做一個連結,才能正常啟用驗證功能。我們建立兩個 Model,並將其中一個Model (ProductDto) 以參數的型態放入另一個Model (ProductCategoryDto)內,並建立分別的 Validator 寫入想要的驗證,且在ProductCategoryValidator 內放 ProductValidator (如兩個Validator之間沒有連結 ProductCategoryDto 內的ProductList 會無法驗證)。

再次啟用 Swagger 後,呼叫內有 ProductCategoryDto 的函式,就可以對子內容(ProductDto)進行驗證(圖五)。

圖五 Swagger

以上 FluentValidation 介紹了驗證的方法與進階的子內容驗證方式,下一篇我們會說到如何對 Model 與資料表的內容做快速的轉換與對應,

那我們下一篇見~

--

--