しばやん雑記

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

ASP.NET MVC 3 で追加された Compare, Remote 検証属性を使ってみる

ASP.NET MVC 3 には System.ComponentModel.DataAnnotations に用意されている検証属性以外にも、CompareAttribute と RemoteAttribute といった専用の検証属性が追加されています。それでは早速 CompareAttribute から使ってみます。

CompareAttribute

名前からわかるように他のプロパティの値と同じかどうか調べる検証属性です。一般的な使い道はパスワードや Eメールアドレスの確認入力だと思います。よくユーザー登録画面でもう一度パスワードやメールアドレスを入力させて、異なっていたらエラーを表示する奴がありますよね、アレです。

では、さくっとモデルクラスに以下のようにプロパティを追加しましょう。

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

[Required]
[Compare("Password", ErrorMessage = "パスワードが異なります。")]
public string ConfirmPassword { get; set; }

Compare の引数には比較したい他のプロパティ名を指定します。文字列での指定がダサいとか言っちゃダメです、属性にはラムダは使えないのです。

MVC 3 プロジェクト作成時に作られるモデルクラスでも使われているので、簡単に試すことが出来ます。

RemoteAttribute

こっちは名前からはちょっと想像しにくいかもしれないです。例えばユーザー登録などでユーザーIDを決める必要がある時に入力したユーザーIDが既に使われていないか確認しますよね。MVC 2 まではデータベース参照や複雑な検証を行う場合には POST 時にモデルバインダに任せるか、自分で頑張って検証するしかなかったのですが Remote を使えばクライアントサイド検証を行うことが出来ます。

こっちも手っ取り早くコードを書いてみましょう。MVC 開発経験がある方なら、引数を見ただけで理解できるレベルです。

まずはモデルクラスにプロパティを追加します。

// アクション、コントローラの順
[Remote("CheckUserId", "Account", ErrorMessage = "既にこのユーザーIDは使用されています。")]
public string UserId { get; set; }

もう、一目見るだけで分かりますね。Remote は入力があるたびに引数で指定されたコントローラのアクションに XHR で通信を行って、アクションで検証を行うこと出来る属性です。コントローラ側で検証を行えるので、データベースを参照する必要がある検証でも簡単に処理が出来るわけです。

今回は AccountController.CheckUserId にアクセスして検証を行うようにしています。

では次はコントローラ側のコードを書いてみましょう。

// 引数はプロパティ名に合わせる必要がある
public ActionResult CheckUserId(string UserId)
{
    // JSON 形式で true か false を返す
    return Json(UserId != "shibayan", JsonRequestBehavior.AllowGet);
}

流石に DB 周りのコードを準備するのは大変だったので、今回はユーザー ID が "shibayan" 以外なら利用可能という形にします。Json 形式で true, false を返すだけなのでシンプルですね。

ビューを作成する時には Reference script libraries にチェックを入れるのを忘れないようにしてください。チェックを入れないと jQuery が読み込まれません。

それでは実際に試してみました。shibayan と入力したときにはちゃんとエラーが表示されています。

本当に通信しているのか確認するために、IE9 のネットワークキャプチャ機能を使って確認しました。

入力ごとに XHR で通信が行われていることが確認できますね。クライアントサイド検証を使っていきたいと思える機能だと思います。