しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

ASP.NET MVC 3 で対応した IValidatableObject とは何か

これまではデータアノテーションを使って検証を行ってきましたが、今回は MVC 3 からサポートされた IValidatableObject インターフェースを使って検証を行いたいと思います。IValidatableObject インターフェースについての基本的な情報は MSDN に載っています。ちなみに .NET Framework 4 から BCL に追加されました。

IValidatableObject インターフェイス (System.ComponentModel.DataAnnotations)

この IValidatableObject はモデルクラスに Validate メソッドを実装することで検証を行いますので、複数のプロパティを参照しての検証が可能になっています。Validate メソッドは IEnumerable を返す必要があるので yield を使ってあげましょう。

それではいつものようにコードを書いていきます。いいサンプルが思いつかなかったので確認パスワードの検証をやってみます。

public class RegisterModel : IValidatableObject
{
    [Required]
    public string UserName { get; set; }

    [Required]
    public string Password { get; set; }

    [Required]
    public string ConfirmPassword { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        // 確認用パスワードが異なっているか調べる
        if (Password != ConfirmPassword)
        {
            // エラーメッセージとエラーを表示するプロパティ名を指定してオブジェクトを返す
            yield return new ValidationResult("パスワードが異なります。", new[] { "ConfirmPassword" });
        }
    }
}

MVC 3 では Compare 属性を使えば同じことは出来るのですが、今回はサンプルということでわかりやすさを重視しました。Validate メソッドでは値の検証を行って、ValidationResult を返しているだけなので説明は不要かと。

データアノテーションとの共存もできるので、必須や範囲などの基本的な検証はデータアノテーション、他のプロパティの値との比較などデータアノテーションで実現できない複雑な検証に関しては IValidatableObject を実装という形が一番いいと思います。

Entity Framework CTP5 ではモデルに定義した検証属性や IValidatableObject を使って、DB 登録時にさらに検証を行う機能が追加されているのですが、それはまた次回に別のエントリで書きたいと思います。