ASP.NET MVC 3とIValidatableObject
ASP.NET MVC 2には、ASP.NET MVCのモデルのバインディング・インフラストラクチャも使用して、自動的にモデルオブジェクト上のDataAnnotation属性に従い、強制実行するサポートが含まれていました。
ASP.NET MVC 3では、さらに進み、IValidatableObjectインターフェイスにも従います。モデル検証に対するこの組み合わせのサポートにより、検証エラーが発生した時に、適切なエラーメッセージを表示することが簡単になります。
この動きを確認するために、ユーザーがProductを新規作成できる簡単なCreateフォームを考えてみましょう。

以下のように、2つの「Create」アクションメソッドを持つProductsControllerクラスを使用して、上記のCreate機能を実装できます。

1つ目のCreateメソッドは、HTTP-GETリクエストを処理して、入力用のHTMLフォームを表示する/Products/Create URLのバージョンを実装します。2つ目のCreateメソッドは、HTTP-POSTリクエストを処理して、送信されたフォームのデータを取得し、それらが有効かどうかを確認し、もし有効であればデータベースへ保存する/Products/Create URLのバージョンを実装します。もし検証エラーがあった場合、その入力された値を再表示します。
「Create」ビューのRazorビューテンプレート(フォームを描画する)は以下のようになります。

上記のコントローラ+ビューの実装でいいところの1つが、その中に検証ロジックを1つも書いていないことです。検証ロジックとビジネスルールは、その代わり、モデル層内全体で実装されます。ProductsControllerは、その変更を保存するのか、エラーのあるフォームを再表示するのかを決定するために(ModelState.IsValidヘルパーメソッドを呼び出して)データの有効性をチェックするだけです。
ビュー内のHtml.ValidationMessageForヘルパーメソッドの呼び出しでは、ProductモデルのDataAnnotationsとIValidatableObject.Validateメソッドが返したエラーメッセージを表示するだけです。
フォームに無効な値を入力して、送信してみれば、上記のシナリオの動作確認ができます。

[Create]ボタンを押したときに、どのようにエラーメッセージが取得されるのか確認してください。
これは、[Discontinued]のチェックボックスをチェックして、UnitsOnOrderの値を入力(これはビジネスルールに1つ違反しています)しているためです。
ASP.NET MVCが、どのようにそのエラーメッセージを強調して、UnitsOnOrderテキストボックスの横に表示したのか疑問に思われるかもしれません。これは、ASP.NET MVC 3が、モデルのバインディングを実施する時にIValidatableObjectインターフェイスに従い、検証に失敗したエラーメッセージを取得するようになったからです。
Productモデルクラスにあるビジネスルールには、違反された時に「UnitsOnOrder」プロパティを強調することが示されています。

設定しているプロパティ名がヒントになるため、Html.ValidationMessageForヘルパーメソッドは、ビジネスルールのエラーメッセージを(UnitsOnOrderの編集ボックスの横に)表示することが分かるのです。

DRYに保つ
ASP.NET MVCおよびEFコードファーストにより、1か所で検証とビジネスルールを保持し(モデル層内で)、コントローラとビューを調べ回る必要がありません。
モデル層に検証ロジックを保持すると、アプリケーションにさらにコントローラやビューを追加した時に、検証/ビジネスロジックが重複しなくなります。これにより、1か所(モデル層)で検証/ビジネスロジックを素早く変更し、アプリケーションにあるすべてのコントローラ/ビューにそれを即座に反映できます。また、アプリケーションのコードをクリーンで保守しやすくし、今後のアプリケーションの展開や更新がより簡単になります。
まとめ
EFコードファースト(CTP5以降)では、DataAnnotationsおよびIValidatableObjectインターフェイスが両方ともサポートされています。このため、モデルへ検証およびビジネスルールを追加して、データベースに変更が永続化される時、EFが必ずそれらを自動的に実行することが、簡単にできるようになります。
ASP.NET MVC 3も、DataAnnotationsおよびIValidatableObjectの両方をサポートするようになっています。そのため、EFコードファーストのモデル層でそれらを使用し、Web層内のコントローラ/ビューに自動的にそれらに従いサポートさせることが、さらに簡単になりました。これにより、クリーンで保守性の高いアプリケーションを構築することが簡単になります。
検証/ビジネスロジックを実施するために、DataAnnotationsまたはIValidatableObjectを使用する必要はありません。お好みで、独自の検証アーキテクチャを適用したり、より上級な検証フレームワーク/パターンを使用できます。しかしながら、多くのアプリケーションでは、このビルトインサポートが、恐らく十分で、ソリューションをビルドする生産性の高い方法になると思います。
Hope this helps,
Scott
P.S. ブログに加え、現在Twitterを使って簡単な更新やリンク共有を行っています。twitter.com/scottguで、私をフォローしてください。
