本文へスキップ
BecomeCoder

C#実践コース · 第6章 代表的なNuGetパッケージとその使い方 · レッスン34

FluentValidation ― 入力検証を宣言的に書く(ローカル実施)

ローカル実施

導入

「名前は必須」「年齢は0〜150」「メール形式が正しいこと」——こうした入力検証ifの羅列で書くと、読みにくく漏れも出ます。FluentValidationは検証ルールを流れるような1つの記述(Fluentインターフェース)でまとめ、エラーメッセージも一元管理できます。

図解

flowchart LR
    IN["入力オブジェクト<br/>User"] --> VAL["UserValidator<br/>RuleFor(...).NotEmpty()..."]
    VAL --> OK["IsValid = true"]
    VAL --> NG["Errors<br/>(項目ごとの失敗理由)"]

進め方

  1. スターター118-fluentvalidation/starter.zipを展開し、ValidationLesson.slnを開く(FluentValidation導入済み)
  2. UserValidatorのTODO(ルール)を埋める
  3. 不正な入力でエラーメッセージが出ることを確認する
Visual StudioでFluentValidationを実行し、空の名前と範囲外の年齢に対して検証エラーメッセージが表示された様子
ルール違反ごとに、指定したメッセージが列挙される

学ぶこと

using FluentValidation;

public class UserValidator : AbstractValidator<User>
{
    public UserValidator()
    {
        RuleFor(u => u.Name).NotEmpty().WithMessage("名前は必須です");
        RuleFor(u => u.Age).InclusiveBetween(0, 150).WithMessage("年齢は0〜150です");
        RuleFor(u => u.Email).EmailAddress().WithMessage("メール形式が不正です");
    }
}

// 使う側
var result = new UserValidator().Validate(new User("", 200, "bad"));
if (!result.IsValid)
    foreach (var e in result.Errors)
        Console.WriteLine(e.ErrorMessage);

record User(string Name, int Age, string Email);
  • AbstractValidator<T>継承し、コンストラクタでRuleFor(...)を並べる
  • NotEmpty / InclusiveBetween / EmailAddressなど豊富な組み込みルールをつなげて書ける
  • ValidateValidationResultを返し、IsValidErrorsで結果を受け取る
  • 検証ロジックをモデルの外にまとめられるので、テストしやすく再利用しやすい(ASP.NET Coreと統合も可能)

期待される出力

名前は必須です
年齢は0〜150です
メール形式が不正です

まとめ

  • FluentValidationは検証ルールをRuleForで宣言的にまとめる
  • IsValidErrorsで結果を受け取り、メッセージも一元管理できる
  • ifの羅列より読みやすく、テストしやすい

次回: 一時的な失敗に強くするPollyです。

テンプレート構成(教材制作用メモ)

118-fluentvalidation/
├── starter.zip   # FluentValidation導入済み / Program.cs(TODO入り)
└── solution/Program.cs