Question

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.

Was it helpful?

Solution

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top