问题
The problem is: when I put 2 controls of the same type on a page I need to specify different prefixes for binding. In this case the validation rules generated right after the form are incorrect. So how to get client validation work for the case?:
the page contains:
<%
Html.RenderPartial(ViewLocations.Shared.PhoneEditPartial, new PhoneViewModel { Phone = person.PhonePhone, Prefix = "PhonePhone" });
Html.RenderPartial(ViewLocations.Shared.PhoneEditPartial, new PhoneViewModel { Phone = person.FaxPhone, Prefix = "FaxPhone" });
%>
the control ViewUserControl<PhoneViewModel>:
<%= Html.TextBox(Model.GetPrefixed("CountryCode"), Model.Phone.CountryCode) %>
<%= Html.ValidationMessage("Phone.CountryCode", new { id = Model.GetPrefixed("CountryCode"), name = Model.GetPrefixed("CountryCode") })%>
where Model.GetPrefixed("CountryCode")
just returns "FaxPhone.CountryCode" or "PhonePhone.CountryCode" depending on prefix
And here is the validation rules generated after the form. They are duplicated for the field name "Phone.CountryCode". While the desired result is 2 rules (required, number) for each of the FieldNames "FaxPhone.CountryCode", "PhonePhone.CountryCode" alt text http://www.freeimagehosting.net/uploads/37fbe720bf.png
The question is somewhat duplicate of Asp.Net MVC2 Clientside Validation and duplicate ID's problem but the advise to manually generate ids doesn't helps.
回答1:
Correct way to set the same prefixes both for textbox and validation:
<% using (Html.BeginHtmlFieldPrefixScope(Model.Prefix)) { %>
<%= Html.TextBoxFor(m => m.Address.PostCode) %>
<%= Html.ValidationMessageFor(m => m.Address.PostCode) %>
<% } %>
where
public static class HtmlPrefixScopeExtensions
{
public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix)
{
return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix);
}
private class HtmlFieldPrefixScope : IDisposable
{
private readonly TemplateInfo templateInfo;
private readonly string previousHtmlFieldPrefix;
public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix)
{
this.templateInfo = templateInfo;
previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix;
templateInfo.HtmlFieldPrefix = htmlFieldPrefix;
}
public void Dispose()
{
templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix;
}
}
}
(by chance found the solution in the code on Steve Sanderson's blog http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/)
Also looks like Html.EditorFor approach should work as well as suggested here: ASP.NET MVC 2 - ViewModel Prefix
来源:https://stackoverflow.com/questions/2759167/asp-net-mvc2-clientside-validation-problem-with-controls-with-prefixes