前回のサンプルに検証機能を追加してみる。
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 件のコメント:
コメントを投稿