これまではデータアノテーションを使って検証を行ってきましたが、今回は MVC 3 からサポートされた IValidatableObject インターフェースを使って検証を行いたいと思います。IValidatableObject インターフェースについての基本的な情報は MSDN に載っています。ちなみに .NET Framework 4 から BCL に追加されました。
IValidatableObject インターフェイス (System.ComponentModel.DataAnnotations)
この IValidatableObject はモデルクラスに Validate メソッドを実装することで検証を行いますので、複数のプロパティを参照しての検証が可能になっています。Validate メソッドは IEnumerable
それではいつものようにコードを書いていきます。いいサンプルが思いつかなかったので確認パスワードの検証をやってみます。
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 登録時にさらに検証を行う機能が追加されているのですが、それはまた次回に別のエントリで書きたいと思います。