前回のサンプルに検証機能を追加してみる。
Viewの設定
まずはエラーが有った時に表示する文言をViewに設定しておく。
- <body>
- <div>
- <% using (Html.BeginForm("MyPost", "HelloWorld", FormMethod.Post))
- {%>
- <label>名前:</label>
- <%: Html.TextBox("name","<初期値>") %>
- <%: Html.ValidationMessage("name", "必須未入力エラーです", new { @Style = "color:red;font-weight:bold;" })%>
- <input type="submit" value="送信" />
- <% } %>
- </div>
- </body>
追加したのは7行目。
HtmlはViewPageクラスのHtmlプロパティでHtmlHelper型。そのValidationMessageメソッドを呼び出すとModelStateDictionaryの中身を調べて第1引数で指定したコントロールにエラーが有るか調べてくれる。エラーが有った場合は第2引数で指定したメッセージをHTMLとして出力する。第3引数はそのメッセージのStyleと言った感じだ。
実際ModelStateDictionaryの中身を作るのはコントローラー側の仕事だ。
ちなみに、ValidationMessageメソッドは拡張メソッドになっていて、実際にはValidationExtensionsクラスで実装されている。
コントローラーでエラーチェック
View側で表示の準備が出来たので、こんどはコントローラー側で入力チェックを行い、エラーがあればModelStateDictionaryにエラー内容を突っ込んでいけば良い。
ModelStateDictionaryはControllerクラスのModelStateプロパティで参照可能だ。
- [HttpPost]
- public ActionResult MyPost(string name)
- {
- if (String.IsNullOrEmpty(name)){ModelState.AddModelError("name", "");}
- if (!ModelState.IsValid) { return View(); }
- ViewData["HelloName"] = "Hello " + name;
- return View("Result");
- }
ここでは、単純にPostされてきたname引数が空だったらModelStateDictionaryのAddModelErrorメソッドでエラーを追加している。
第1引数がエラーのあったコントロール、第2引数がエラーメッセージ。
(View側でエラーメッセージまで定義したのでとりあえずこちらでは何も指定してない。)
実際には、ここで様々な入力項目のチェックを行い、その結果1つでもエラーが有ったかどうかを6行目のIsValidプロパティで判定することになる。
エラーが無ければ9行目で結果画面を表示させるし、エラーがあればそのままView画面に差し戻しといった感じである。
結果
エラー表示にスタイルシートを使う
上記エラー画面のソースは以下のようになっている。
5行目、6行目を見ると「input-validation-error」、「field-validation-error」というクラス名が付与されているのが判る。
HtmlHelperクラスがエラーに応じて付与してくれるのだろう。
MVCプロジェクトには予めSite.cssというスタイルシートが用意されているので、それを使えば良いようだ。
スタイルシートを使うように変更したソースは以下の通り。
- <body>
- <div>
- <form action="/HelloWorld/MyPost" method="post">
- <label>名前:</label>
- <input class="input-validation-error" id="name" name="name" type="text" value="" />
- <span Style="color:red;font-weight:bold;" class="field-validation-error">必須未入力エラーです</span>
- <input type="submit" value="送信" />
- </form>
- </div>
- </body>
- <head runat="server">
- <title>MyPost</title>
- <link rel="Stylesheet"
- type="text/css" href="../../Content/Site.css"/>
- </head>
- <body>
- <div>
- <% using (Html.BeginForm("MyPost", "HelloWorld", FormMethod.Post))
- {%>
- <label>名前:</label>
- <%: Html.TextBox("name","<初期値>") %>
- <%-- <%: Html.ValidationMessage("name", "必須未入力エラーです", new { @Style = "color:red;font-weight:bold;" })%>
- --%>
- <%: Html.ValidationMessage("name", "必須未入力エラーです")%>
- <input type="submit" value="送信" />
- <% } %>
- </div>
- </body>
3行目でスタイルシートへの参照を追加して、12行目して指定していた個別のスタイル指定を削除した。
しかし、これで実行すると、
といった表示になってしまい、なんとなくイマイチ。
あー、このスタイルシートはデフォルトで作られている以下のページ用なのね・・・。
さしあたって、Validation関係のスタイル以外は削除し以下の通りとした。
- /* Styles for validation helpers
- -----------------------------------------------------------*/
- .field-validation-error
- {
- color: #ff0000;
- }
- .field-validation-valid
- {
- display: none;
- }
- .input-validation-error
- {
- border: 1px solid #ff0000;
- background-color: #ffeeee;
- }
- .validation-summary-errors
- {
- font-weight: bold;
- color: #ff0000;
- }
- .validation-summary-valid
- {
- display: none;
- }
サマリーエラーの表示
よくあるパターンとして、エラー内容を個々に表示するのではなく、サマリーとして纏めて表示する方法がある。
それには、Html.ValidationSummaryメソッドを使うと良い。
エラーチェック(Actionメソッド)側では、ModelState.AddModelError("name", "サマリーエラー")としてエラーメッセージを指定する。
- [HttpPost]
- public ActionResult MyPost(string name)
- {
- if (String.IsNullOrEmpty(name)){ModelState.AddModelError("name", "サマリー用エラー発生");}
- if (!ModelState.IsValid) { return View(); }
- ViewData["HelloName"] = "Hello " + name;
- return View("Result");
- }
- }
- <body>
- <div>
- <% using (Html.BeginForm("MyPost", "HelloWorld", FormMethod.Post))
- {%>
- <label>名前:</label>
- <%: Html.TextBox("name","<初期値>") %>
- <%-- <%: Html.ValidationMessage("name", "必須未入力エラーです", new { @Style = "color:red;font-weight:bold;" })%>
- --%>
- <%: Html.ValidationMessage("name", "必須未入力エラーです")%>
- <%=Html.ValidationSummary("以下のエラーが発生しました。")%>
- <input type="submit" value="送信" />
- <% } %>
- </div>
- </body>
0 件のコメント:
コメントを投稿