✅ バリデーションデモ

Data Annotations・ModelState・Service層バリデーションの連携を体験できるデモ

📚 バリデーションの3分類

バリデーションは実装層によって3つに分類されます。

分類 実装層 実装方法
単項目チェック Controller Data Annotations → ModelState 必須・文字数・形式
複数項目関連チェック Service ValidationException 与信限度額超過
業務タイミングチェック Service ValidationException + DB参照 顧客存在確認・重複チェック
RequestDTO(Data Annotations)
public class OrderRequest
{
    [Required(ErrorMessage = "顧客コードは必須です")]
    [MaxLength(10, ErrorMessage = "10文字以内で入力してください")]
    public string? CustomerCode { get; set; }

    [Range(1, int.MaxValue, ErrorMessage = "1以上で入力してください")]
    public int Quantity { get; set; }

    [Required]
    [EmailAddress(ErrorMessage = "形式が不正です")]
    public string? Email { get; set; }
}
Controller(ModelState チェック)
public IActionResult CreateOrder(
    [FromBody] OrderRequest request)
{
    if (!ModelState.IsValid)
    {
        var errors = ModelState
            .Where(kv => kv.Value?.Errors.Count > 0)
            .SelectMany(kv => kv.Value!.Errors
                .Select(e => new ValidationError(kv.Key, e.ErrorMessage)))
            .ToList();
        throw new ValidationException(errors);
    }
    _service.ValidateOrder(request); // Service層へ
    return Ok(...);
}

🧪 注文フォームでバリデーションを体験

フォームに値を入力して送信すると、Controller層→Service層のバリデーションが順番に動作します。

登録済み顧客: C001(与信1万円), C002(与信5千円), C003(与信5万円)
⚡ クイック入力(バリデーションエラーのパターンを即体験)

💻 レスポンス

← フォームを送信するとここにレスポンスが表示されます

⚙️ バリデーションフロー

リクエストが来てからレスポンスを返すまでの流れ:

Client → Controller
         ↓
    ModelState.IsValid? ──No──→ 400 (ValidationError: 単項目エラー)
         ↓ Yes
    Service.ValidateOrder()
         ↓
    顧客コード存在チェック ──NG──→ 400 (ValidationError: 存在しません)
         ↓ OK
    与信限度額チェック ──NG──→ 400 (ValidationError: 限度額超過)
         ↓ OK
    重複注文チェック ──NG──→ 400 (ValidationError: 重複あり)
         ↓ OK
    200 OK(注文登録成功)

ポイント:どの層でエラーが発生しても ValidationExceptionExceptionHandlingMiddleware が同じ形式のJSONを返します。

🔗 参考リンク