ページ

2011年12月12日月曜日

◆ASP.NET MVC 検証機能を追加する

前回のサンプルに検証機能を追加してみる。

Viewの設定

まずはエラーが有った時に表示する文言をViewに設定しておく。

  1. <body>  
  2.     <div>  
  3.     <% using (Html.BeginForm("MyPost", "HelloWorld", FormMethod.Post))  
  4.        {%>  
  5.            <label>名前:</label>  
  6.            <%: Html.TextBox("name","<初期値>") %>  
  7.            <%: Html.ValidationMessage("name", "必須未入力エラーです", new { @Style = "color:red;font-weight:bold;" })%>  
  8.            <input type="submit" value="送信" />  
  9.       <% } %>  
  10.       
  11.     </div>  
  12. </body>  

追加したのは7行目。
HtmlはViewPageクラスのHtmlプロパティでHtmlHelper型。そのValidationMessageメソッドを呼び出すとModelStateDictionaryの中身を調べて第1引数で指定したコントロールにエラーが有るか調べてくれる。エラーが有った場合は第2引数で指定したメッセージをHTMLとして出力する。第3引数はそのメッセージのStyleと言った感じだ。
実際ModelStateDictionaryの中身を作るのはコントローラー側の仕事だ。


ちなみに、ValidationMessageメソッドは拡張メソッドになっていて、実際にはValidationExtensionsクラスで実装されている。


コントローラーでエラーチェック


View側で表示の準備が出来たので、こんどはコントローラー側で入力チェックを行い、エラーがあればModelStateDictionaryにエラー内容を突っ込んでいけば良い。
ModelStateDictionaryはControllerクラスのModelStateプロパティで参照可能だ。


  1. [HttpPost]  
  2. public ActionResult MyPost(string name)  
  3. {  
  4.     if (String.IsNullOrEmpty(name)){ModelState.AddModelError("name""");}  
  5.   
  6.     if (!ModelState.IsValid) { return View(); }  
  7.   
  8.     ViewData["HelloName"] = "Hello " + name;  
  9.     return View("Result");  
  10. }  

 


ここでは、単純にPostされてきたname引数が空だったらModelStateDictionaryのAddModelErrorメソッドでエラーを追加している。
第1引数がエラーのあったコントロール、第2引数がエラーメッセージ。
(View側でエラーメッセージまで定義したのでとりあえずこちらでは何も指定してない。)


実際には、ここで様々な入力項目のチェックを行い、その結果1つでもエラーが有ったかどうかを6行目のIsValidプロパティで判定することになる。
エラーが無ければ9行目で結果画面を表示させるし、エラーがあればそのままView画面に差し戻しといった感じである。


結果


2011-11-28 11h18_47


エラー表示にスタイルシートを使う


上記エラー画面のソースは以下のようになっている。


5行目、6行目を見ると「input-validation-error」、「field-validation-error」というクラス名が付与されているのが判る。
HtmlHelperクラスがエラーに応じて付与してくれるのだろう。
MVCプロジェクトには予めSite.cssというスタイルシートが用意されているので、それを使えば良いようだ。


スタイルシートを使うように変更したソースは以下の通り。


  1. <body>  
  2.     <div>  
  3.     <form action="/HelloWorld/MyPost" method="post">  
  4.            <label>名前:</label>  
  5.            <input class="input-validation-error" id="name" name="name" type="text" value="" />  
  6.            <span Style="color:red;font-weight:bold;" class="field-validation-error">必須未入力エラーです</span>  
  7.            <input type="submit" value="送信" />  
  8.       </form>  
  9.       
  10.     </div>  
  11. </body>  

  1. <head runat="server">  
  2.     <title>MyPost</title>  
  3.     <link rel="Stylesheet"  
  4.        type="text/css" href="../../Content/Site.css"/>  
  5. </head>  
  6. <body>  
  7.     <div>  
  8.     <% using (Html.BeginForm("MyPost", "HelloWorld", FormMethod.Post))  
  9.        {%>  
  10.            <label>名前:</label>  
  11.            <%: Html.TextBox("name","<初期値>") %>  
  12. <%--           <%: Html.ValidationMessage("name", "必須未入力エラーです", new { @Style = "color:red;font-weight:bold;" })%>  
  13. --%>  
  14.            <%: Html.ValidationMessage("name", "必須未入力エラーです")%>  
  15.            <input type="submit" value="送信" />  
  16.       <% } %>  
  17.       
  18.     </div>  
  19. </body>  

3行目でスタイルシートへの参照を追加して、12行目して指定していた個別のスタイル指定を削除した。


しかし、これで実行すると、


2011-11-28 11h57_22


といった表示になってしまい、なんとなくイマイチ。
あー、このスタイルシートはデフォルトで作られている以下のページ用なのね・・・。
2011-11-28 11h58_59


さしあたって、Validation関係のスタイル以外は削除し以下の通りとした。


  1. /* Styles for validation helpers 
  2. -----------------------------------------------------------*/  
  3. .field-validation-error  
  4. {  
  5.     color#ff0000;  
  6. }  
  7.   
  8. .field-validation-valid  
  9. {  
  10.     displaynone;  
  11. }  
  12.   
  13. .input-validation-error  
  14. {  
  15.     border1px solid #ff0000;  
  16.     background-color#ffeeee;  
  17. }  
  18.   
  19. .validation-summary-errors  
  20. {  
  21.     font-weightbold;  
  22.     color#ff0000;  
  23. }  
  24.   
  25. .validation-summary-valid  
  26. {  
  27.     displaynone;  
  28. }  

サマリーエラーの表示


よくあるパターンとして、エラー内容を個々に表示するのではなく、サマリーとして纏めて表示する方法がある。


それには、Html.ValidationSummaryメソッドを使うと良い。
エラーチェック(Actionメソッド)側では、ModelState.AddModelError("name", "サマリーエラー")としてエラーメッセージを指定する。


  1.     [HttpPost]  
  2.     public ActionResult MyPost(string name)  
  3.     {  
  4.         if (String.IsNullOrEmpty(name)){ModelState.AddModelError("name""サマリー用エラー発生");}  
  5.   
  6.         if (!ModelState.IsValid) { return View(); }  
  7.   
  8.         ViewData["HelloName"] = "Hello " + name;  
  9.         return View("Result");  
  10.     }  
  11. }  

  1. <body>  
  2.     <div>  
  3.     <% using (Html.BeginForm("MyPost", "HelloWorld", FormMethod.Post))  
  4.        {%>  
  5.            <label>名前:</label>  
  6.            <%: Html.TextBox("name","<初期値>") %>  
  7. <%--           <%: Html.ValidationMessage("name", "必須未入力エラーです", new { @Style = "color:red;font-weight:bold;" })%>  
  8. --%>  
  9.            <%: Html.ValidationMessage("name", "必須未入力エラーです")%>  
  10.            <%=Html.ValidationSummary("以下のエラーが発生しました。")%>  
  11.            <input type="submit" value="送信" />  
  12.       <% } %>  
  13.       
  14.     </div>  
  15. </body>  

0 件のコメント:

コメントを投稿

私が最近チェックした記事