本篇會做 Web API 的 Request 驗證。
用 FluentValidaiton ( NuGet 套件 ),在 Visual Studio 用 C# 寫範例程式碼。
之前單元測試Unit Test (二)─實例撰寫過程─面積計算功能是用 FluentAssertions ( NuGet 套件 )。
上一篇設計完 Web API 的規格,這篇開始依照規格寫 API。
用 POST 方法建立同業合作契約 (Cobroke Letter) 的API,範例程式碼如下
[HttpPost]
public IActionResult CreateCobrokeLetter(CreateCobrokeLetterRequest request)
{
//---本篇重點要講的驗證---
var validator = new CreateCobrokeLetterRequestValidator();
var validationResult = validator.Validate(request);
if (!validationResult.IsValid)
{
return BadRequest(validationResult.Errors);
}
//---本篇重點要講的驗證---
var cobrokeLetterId = _cobrokeLetterService.CreateCobrokeLetter(request);
var response = new CreateCobrokeLetterResponse()
{
Message = $"Successfully Create Cobroke Letter Id = {cobrokeLetterId}."
};
//return Ok(response);
return CreatedAtAction(nameof(GetCobrokeLetter), new { id = cobrokeLetterId }, response);
}
我們要驗證使用者給的 Request 是不是有符合API的設計,防止API因為不合的Request而爆炸。
因此我們要寫驗證 (Validation) 抓出因為不合的Request造成的錯誤,並丟出錯誤訊息提醒使用者哪裡錯了。
步驟一、加入專案
- 加入專案 ─ ASP.NET Core Web API。
Visual Studio 會自動幫我們建立Controller、http檔。
→要用來寫API Http方法
e.g.,檔名:Esign.Api
- 加入專案 ─ MSTest測試專案
→用來寫API Request的validation單元測試,撰寫過程寫好的Production Code會放在Service層。
e.g.,檔名:Esign.Service
- 加入專案 ─ 類別庫
→作為Service層,用來放Production Code。
e.g.,檔名:Esign.Service.Test
並加入【專案參考】:
- Esign.Service.Test 參考 Esign.Service
- Esign.Api 參考 Esign.Service
步驟二、下載FluentValidation套件
FluentValidation 可以幫我們將 API 傳入的參數的檢查用更口語、更乾淨的方式去處理,
除了可以將檢查邏輯拆分成單獨的 Validator 類別,更提供了許多內建的檢查規則和自訂的彈性,相當方便。
並且因為將參數的檢查邏輯整理出去,就可以和 Controller 本身的工作做簡單的拆分,達到關注點分離的目標。
步驟三、依照 Web API Spec 寫 Request 的 Validation 單元測試
輸入testc按兩下tab鍵,IDE自動建立TestClass
。
輸入testm按兩下tab鍵,IDE自動建立TestMethod
。
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
}
}
先寫情境一、驗證建立契據人編號必為6碼
/// <summary>
/// 建立同業合作契約請求參數驗證測試
/// </summary>
[TestClass]
public class CreateCobrokeLetterRequestValidateTests
{
/// <summary>
/// 情境一、驗證建立契據人編號必為6碼
/// </summary>
[TestMethod]
public void CreatedUserId_Not_Six_Number_Is_Invalid()
{
// Arrange
// 加入一個建立契據人編號不為6碼的請求
var request = new CreateCobrokeLetterRequest
{
CreatedUserId = "12345"
};
// 建立驗證器
var validator = new CreateCobrokeLetterRequestValidator();
// Act 執行驗證
var validateResult = validator.TestValidate(request);
// Assert 驗證結果
validateResult.ShouldHaveValidationErrorFor(x => x.CreatedUserId)
.WithErrorMessage("CreatedUserId must be 6 digits in length.");
}
}
CreateCobrokeLetterRequestValidator
的 Validator 繼承 AbstractValidator<T>
using FluentValidation;
namespace Esigning.Service
{
/// <summary>
/// 建立同業合作契約請求參數驗證器
/// </summary>
public class CreateCobrokeLetterRequestValidator : AbstractValidator<CreateCobrokeLetterRequest>
{
/// <summary>
/// 建構式
/// </summary>
public CreateCobrokeLetterRequestValidator()
{
//CreatedUserId長度不是6碼&沒有填寫就會出現錯誤訊息
RuleFor(x => x.CreatedUserId).Length(6).WithMessage("CreatedUserId must be 6 digits in length.")
.NotNull().NotEmpty().WithMessage("EmployeeNumber cannot be null and empty.");
}
}
}
.Length(6)
:會驗證Request的CreatedUserId
參數長度必須是6。
.WithMessage("CreatedUserId must be 6 digits in length.")
:前面的條件如果不符合會出現錯誤訊息。
.NotNull().NotEmpty()
:會驗證CreatedUserId
參數必填。
通過單元測試
步驟四、完成所有驗證規則後,寫進API
[HttpPost]
public IActionResult CreateCobrokeLetter([FromBody] CreateCobrokeLetterRequest request)
{
//驗證請求參數
var validator = new CreateCobrokeLetterRequestValidator();
var validateResult = validator.Validate(request);
if (!validateResult.IsValid)
{
return BadRequest(validateResult.Errors);
}
//TODO: 使用Service建立同業合作契約
var response = new CreateCobrokeLetterResponse
{
Message = $"Successfully Create Cobroke Letter."
};
return Ok(response);
}
- 先實例化
CreateCobrokeLetterRequestValidator
- 使用
validator
驗證request
- 驗證的結果通過就往下執行去建立
同業合作契約
驗證有問題就回傳BadRequest
與Error Message
這樣就完成 Request 的驗證囉🥳
可以參考我的程式碼 https://github.com/LilyLin395135/EsignAPI.git
下方是上一篇 設計 Web API 規格文件 的範例,本篇用這個Post方法的Request示範Validation的寫法。
資源路徑 URL | 操作名稱 Action Name | HTTP Method | 說明 | 請求參數 Request | 回應 Response |
---|---|---|---|---|---|
/esigning/co-broke-letters | CreateCobrokeLetter | POST | 建立同業合作線上簽名契約 | createRequest | 找到這筆資料的URL, cobrokeLetterId, response 201 Created 已建立 400 Bad Request 錯誤的要求 |
POST ~/esigning/cobroke-letters
功能:建立同業合作契約資料
Action Name:CreateCobrokeLetter
Request 請求參數:createRequest
Body 參數名稱 | 是否必填 | 資料類型 | 說明 |
---|---|---|---|
CreateDate | V | DateTime | 建立契據日期 |
CreateUserId | V | string | 建立契據人編號,6碼數字 |
Listing | V | string | 1 (For Sale);2 (For Rent)。不是1就是2或1,2 |
AskingPrice | decimal | 開價 (For Sale有選,AskingPrice欄位必填) | |
Rental | decimal | 租金 (For Rent有選,Rental欄位必填) |
用 CreateUserId 的規則示範。
參考
伊果的沒人看筆記本─使用 Fluent Validation 來驗證參數吧
謝謝觀看,此為新手的學習筆記整理,若有錯誤,煩請指正🙏