ページ

2011年12月12日月曜日

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

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

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画面に差し戻しといった感じである。


結果


2011-11-28 11h18_47


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


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


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行目して指定していた個別のスタイル指定を削除した。


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


2011-11-28 11h57_22


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


さしあたって、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 件のコメント:

コメントを投稿

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