I have an MVC3 page with an object (Header) that has data and a list of objects (Details) that I want to update on a single page. On the details object I have custom validation (IValidatableObject) that also needs to run.
This appears to generally be working as expected, validations are running and returning ValidationResults and if I put an @Html.ValidationSummary(false); on the page it displays those validations. However I don't want a list of validations at the top, but rather next to the item being validated i.e. Html.ValidationMessageFor which is on the page, but not displaying the relevant message. Is there something I'm missing? This is working on other pages (that don't have this Master-Details situation), so i'm thinking it is something about how I'm going about setting up the list of items to be updated or the editor template for the item?
Edit.cshtml (the Header-Details edit view)
@foreach (var d in Model.Details.OrderBy(d => d.DetailId))
{
@Html.EditorFor(item => d, "Detail")
}
Detail.ascx (the Details Editor Template)
<%@ 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>
Model is Entity Framework with Header that has Name and HeaderId and Detail has DetailId, HeaderId, Description and Amount
Controller Code:
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);
}
}
[I know controller code can be cleaned up a bit, just at this state as a result of trying to determine what is occuring here]
IValidatableObject implementation:
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" });
}
}