まだバージョンも0.5だし、これからなプロジェクトなんだろうけど、これはちょっと目が離せないかも。
ASP.NET MVCでサーバーサイドのバリデーション(入力検証)を行うとき、DynamicDataで導入されたDataAnnotationsを使うのが、現時点ではベストな選択なんじゃないかと思うんだけど、いかんせんサーバーサイドでの属性ベースのテクノロジなので、クライアントサイドでの検証は別途実装しなきゃなところ。 クライアントサイドでの検証があるだけで、入力をいちいちサーバーにポストしなくても何がエラーなのか、入力と同時に分かるから便利だけど、その為に同じルールを何度もコーディングするのは面倒だよね。面倒だけど仕方なく実装する感じ。
そこを橋渡しするのがこのxVal。
DataAnnotationsで属性に指定した検証ルールをJson形式に変換して、クライアントに書き出すことで、ルール定義は1箇所で済ませようという、楽したいがタメに生まれたナイスなプロジェクト。 サーバーサイドの属性の抽出用プロバイダとして、System.ComponentModel.DataAnnotationsだけじゃなく、Castle.Components.Validatorも実装。
クライアントサイドの検証にはjQuery.validateの他にも、ASP.NET標準の検証コントロールを使った実装もある(けど、こっちはあんまり興味なし)。xVal.ClientSidePluginsに入ってるこの2つのクライアントサイドの実装は、たぶんこれ以外にも例えば prototype.js版とか作れるってことだよね。AllPossibleRulesを全部書けば...。誰か作ってくれるんじゃないかな~。作ってくれないかな~。
xVal - a validation framework for ASP.NET MVC « Steve Sanderson’s blog ↑ここで、どんな物なのか書かれてる。
サンプルプロジェクトもあるので、実際に動かしてみるのが分かりやすいね。 って、ことで、早速ダウンロード。
BookingsDemoにはxValのアセンブリは含まれてるけど、ソースは含まれてないのでソースはCodePlexから。
なるほど~。すばらしいくらいリフレクション。 DataTypeRule/RangeRule/RegularExpressionRule/RequiredRule/StringLengthRuleの5つのルールに属性を変換するんだね。
サンプルでレンダリングされるJsonは↓。
<script type="text/javascript"> xVal.AttachValidator("booking", {"Fields":[ {"FieldName":"ClientName","FieldRules":[ {"RuleName":"StringLength","RuleParameters":{"MaxLength":"15"}}, {"RuleName":"Required","RuleParameters":{}}] }, {"FieldName":"NumberOfGuests","FieldRules":[ {"RuleName":"Range","RuleParameters":{"Min":"1","Max":"20","Type":"decimal"}}, {"RuleName":"DataType","RuleParameters":{"Type":"Integer"}}] }, {"FieldName":"ArrivalDate","FieldRules":[ {"RuleName":"DataType","RuleParameters":{"Type":"Date"}}, {"RuleName":"Required","RuleParameters":{}}] }] }) </script>
見ての通り、入力値の単純な検証は変換するけど、ビジネスルールはサーバーサイドのみで実行。 それが、どこにあるのか探してみると、BookingManager.PlaceBooking。 その中で、属性ベースの検証の実行と、ビジネスルールの検証の両方を実装。
アクションはどうやってるのか見てみると
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateBooking(Booking booking)
{
try {
BookingManager.PlaceBooking(booking);
}
catch(RulesException ex) {
ex.AddModelStateErrors(ModelState, "booking");
}
return ModelState.IsValid ? RedirectToAction("Completed")
: (ActionResult) View();
}
RuleException が発生(PlaceBooking内でエラーがあったらスロー)したら、ModelStateにエラーを入れる。これで、JavaScriptオフでも入力検証はきちんと実行されるて、エラーフィールドにはinput-validation-error、エラーメッセージも表示(<%= Html.ValidationMessage(モデル名)%>)されるっていうすばらしさ(ModelState.AddModelErrorでエラーを入れれば、Htmlヘルパー経由の場合、ちゃんと反映されるっていうASP.NET MVCの設計がこういうとき威力を発揮するね)。 RCがなかなかリリースされないけど、この辺見てるだけでも楽しいかも~。 ※RCでは動かなかったりするかもしれないけどね。