Validation(バリデーション)の実装方法と使い分け【C# MVC対応】

システム開発
スポンサーリンク
スポンサーリンク

フォーム入力チェックに欠かせないValidation(バリデーション)ですが、「DataAnnotationsだけで大丈夫?」「ModelStateはどう使い分けるの?」「複雑なValidationはどこに書くべき?」と迷ったことはありませんか?

この記事では、C# / ASP.NET Core MVC における代表的な4つのValidation手法を整理し、実務での使いどころや選定のフローチャートまでを詳しく解説します。

この記事でわかること

  • Validationの種類とそれぞれの使い分け方
  • 実務でのValidation選定フロー
  • ASP.NET Core MVCにおけるValidation実装例

実務で役立つValidation選定ガイド

バリデーションを正しく使い分けることは、実務の効率化・品質向上に直結します。このセクションでは、どのValidation手法をいつ使うべきかを早見表とフローチャートで整理します。

✏️ Validation手法の使い分け早見表

シーン 推奨Validation手法 理由
単純な入力検証 DataAnnotations 宣言的で簡易
複数項目の整合性 IValidatableObject モデル内で完結可能
ステップ入力/動的UI TryValidateModel 部分検証に適応可能
外部連携や独自ロジック ModelState.AddModelError 柔軟なエラー制御

✏️ Validation手法の選定フローチャート

シンプルな検証?
├─ YES → DataAnnotations
└─ NO
   └─ モデルで完結可能?
       ├─ YES → IValidatableObject
       └─ NO
           ├─ 部分検証必要? → TryValidateModel
           └─ 外部連携・複雑? → ModelState.AddModelError

DataAnnotationsによる属性ベースのValidation(バリデーション)

チェックタイミング

  • ASP.NET Core MVCのモデルバインディング完了時に自動でValidationが実行されます。
  • サーバー側では ModelState.IsValid で結果を確認できます。
  • Razorビューと連携している場合、クライアントサイドでもリアルタイム検証が働きます。

ASP.NET Core MVCで最も基本的なValidation手法がDataAnnotationsです。モデルのプロパティにアノテーションを付与することでValidationルールを定義できます。

特徴とメリット

  • ✅ シンプルな構文で基本的なValidation(必須、文字数、形式)に対応
  • ✅ クライアントサイドのValidation(JavaScript)にも連携可能
  • ✅ 小規模なフォームに適しており、実装も簡易

C#のValidation実装例(DataAnnotations)

public class UserViewModel
{
    [Required(ErrorMessage = "メールアドレスは必須です")]
    [EmailAddress(ErrorMessage = "正しいメールアドレス形式で入力してください")]
    public string Email { get; set; }

    [Required(ErrorMessage = "パスワードを入力してください")]
    [StringLength(20, MinimumLength = 6, ErrorMessage = "パスワードは6~20文字で入力してください")]
    public string Password { get; set; }
}

注意点

  • 単項目しかチェックできない
  • 条件付きValidationはカスタム属性が必要

IValidatableObjectによるクロスフィールドValidation

チェックタイミング

  • DataAnnotationsと同様に、モデルバインディング直後Validate() メソッドが自動で呼び出されます。
  • フォーム送信時に ModelState.IsValid をチェックすることで検証結果を利用します。

複数項目の整合性確認を行いたい場合、IValidatableObjectが有効です。たとえば「開始日 < 終了日」などのチェックに適しています。

特徴とメリット

  • ✅ フィールド間の関係性をValidationできる
  • ✅ モデル内部で完結し、凝集性が高く保守しやすい

C#のValidation実装例(IValidatableObject)

public class ReservationViewModel : IValidatableObject
{
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext context)
    {
        if (StartDate > EndDate)
        {
            yield return new ValidationResult("開始日は終了日より前にしてください。",
                new[] { nameof(StartDate), nameof(EndDate) });
        }
    }
}

注意点

  • 外部サービスとの照合には不向き(DIが使えない)

TryValidateModelによる部分Validationの実装

チェックタイミング

  • TryValidateModel() を呼び出したその時点で即時にValidationが実行されます。
  • コントローラ内の任意のタイミングで呼び出せるため、段階的な入力検証に適しています。
  • DataAnnotationsIValidatableObject に定義されたルールが適用されます。

フォームの一部のみを段階的にValidationしたい場合はTryValidateModelが有効です。

特徴とメリット

  • ✅ 任意のオブジェクト・プロパティにValidationを適用可能
  • ✅ ステップフォームやタブごとのValidationに対応

C#のValidation実装例(TryValidateModel)

if (!TryValidateModel(viewModel.AddressPart, "AddressPart"))
{
    return View(viewModel); // エラーあり
}

補足

  • 戻り値はbool
  • ModelStateに自動でエラー追加

ModelState.AddModelErrorによる柔軟なValidationエラー追加

チェックタイミング

  • 明示的に ModelState.AddModelError() を呼び出したその時点でModelStateにエラーが登録されます。
  • 通常は ModelState.IsValid を確認する処理の前に、条件分岐で追加する形式になります。
  • 自動検証ではなく**手動検証(ロジックによる判定)**に基づくタイミング制御が可能です。

API照合や業務ロジックを含む複雑なValidationには、手動でエラーを追加するModelState.AddModelErrorが適しています。

特徴とメリット

  • ✅ 外部サービス照合や条件付きエラーに対応
  • ✅ グローバルエラーや個別エラーの両方に対応

C#のValidation実装例(ModelState.AddModelError)

if (!db.UserExists(model.Email))
{
    ModelState.AddModelError("Email", "このメールアドレスは登録されていません。");
}

if (externalService.HasIssue())
{
    ModelState.AddModelError(string.Empty, "システムで一時的な問題が発生しています。");
}

まとめ:Validationの選定と併用が品質向上のカギ

Validationは単独ではなく、併用が基本です。DataAnnotationsで基本検証、IValidatableObjectで整合性チェック、ModelStateで外部連携や複雑ロジックを補完し、シーンに応じた設計を行いましょう。

ASP.NET Core MVCにおけるValidation設計を初期段階から明確にすることで、保守性と品質が大幅に向上します。

システム開発
スポンサーリンク
tobotoboをフォローする

コメント

タイトルとURLをコピーしました