1つのページで更新するデータとオブジェクトのリスト(詳細)を含むオブジェクト(ヘッダー)を含むMVC3ページがあります。詳細オブジェクトには、実行する必要のあるカスタム検証(IValidatableObject)があります。
これは通常、期待どおりに機能しているように見えます。検証が実行され、ValidationResultsが返されます。また、@ Html.ValidationSummary(false); ページにそれらの検証が表示されます。ただし、検証のリストを上部に表示するのではなく、検証対象のアイテムの横に配置する必要があります。つまり、ページ上にあるが関連するメッセージを表示しないHtml.ValidationMessageForです。足りないものはありますか?これは他のページ(このマスター/詳細の状況がない)で機能しているので、更新するアイテムのリストまたはアイテムのエディターテンプレートを設定する方法についての何かだと思います?
Edit.cshtml(ヘッダー-詳細編集ビュー)
@foreach (var d in Model.Details.OrderBy(d => d.DetailId))
{
@Html.EditorFor(item => d, "Detail")
}
Detail.ascx(詳細エディターテンプレート)
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Detail>" %>
<tr>
<td>
<%= Model.Name %>
<%= Html.HiddenFor(model => model.DetailId) %>
</td>
<td class="colDescription">
<%= Html.EditorFor(model => model.Description) %>
<%= Html.ValidationMessageFor(model => model.Description) %>
</td>
<td class="colAmount">
<%= Html.EditorFor(model => model.Amount) %>
<%= Html.ValidationMessageFor(model => model.Amount) %>
</td>
</tr>
モデルは、NameとHeaderIdを持つヘッダーを持つエンティティフレームワークであり、DetailにはDetailId、HeaderId、Description、Amountがあります
コントローラーコード:
public ActionResult Edit(Header header, FormCollection formCollection)
{
if (formCollection["saveButton"] != null)
{
header = this.ProcessFormCollectionHeader(header, formCollection);
if (ModelState.IsValid)
{
return new RedirectResult("~/saveNotification");
}
else
{
return View("Edit", header);
}
}
else
{
return View("Edit", header);
}
}
[ここで何が起こっているのかを判断しようとした結果、この状態でコントローラーコードを少しクリーンアップできることはわかっています]
IValidatableObjectの実装:
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (this.Name.Length < 5) && (this.Amount > 10))
{
yield return new ValidationResult("Item must have sensible name to have Amount larger than 10.", new[] { "Amount" });
}
}