开发者

Client side validation of list in ASP.Net MVC 2

I've used stackoverflow many a time to solve my problems (code related!) but this is the first time I've needed to post a question cause I cannot work out whats wrong.

When I enable client side validation on a view that allows editing of a collection of objects which use DataAnnotations for validation the following exception is raised:

[KeyNotFoundException: The given key was not present in the dictionary.]
System.Collections.Generic.SortedDictionary`2.get_Item(TKey key) +6129977
System.Web.Mvc.Html.ValidationExtensions.ValidationMessageHelper(HtmlHelper htmlHelper, ModelMetadata modelMetadata, String expression, String validationMessage, IDictionary`2 htmlAttributes) +840
System.Web.Mvc.Html.ValidationExtensions.ValidationMessageFor(HtmlHelper`1 htmlHelper, Expression`1 expression, String validationMessage, IDictionary`2 htmlAttributes) +138
System.Web.Mvc.Html.ValidationExtensions.ValidationMessageFor(HtmlHelper`1 htmlHelper, Expression`1 expression) +106
ASP.views_test_test_aspx.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in d:\SVN\Discover2 - trunk\Discover2.Web\Views\Test\Test.aspx:18
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +109
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
System.Web.UI.Page.Render(HtmlTextWriter writer) +29
System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer) +56
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3060

Line 18:    <%: Html.ValidationMessageFor(m => Model[i].Name)%>

If I remove the <% Html.EnableClientValidation(); %> call no exception is raised and server side validation works as expected.

Here is my test Model:

public class Dog {
  [Required]
  public string Name { get; set; }
}

and view:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<IList<Discover2.Web.Controllers.Dog>>" %>
<% Html.EnableClientValidation(); %>
<%using (Html.BeginForm()) 开发者_开发问答{ %>
<%for (int i = 0; i < Model.Count(); i++) {%>
    <div>
        <%: Html.LabelFor(m => Model[i].Name) %>
        <%: Html.TextBoxFor(m => Model[i].Name)%>
        <%: Html.ValidationMessageFor(m => Model[i].Name)%>
    </div>
 <%} %>
 <button type=submit>Save</button>

Any ideas on how to get this working would be appreciated as its been doing my head in trying to get this to work!!!

Thanks


Finally got to the bottom of this one. Basically the MVC ValidationMessageHelper function was failing to generate an id for the span element generated by the validation helper. The CreateSanitizedId method on the TagBuilder class was returning null because the modelName was "[0].Name" and Id's cannot begin with anything other than a letter. The KeyNotFoundException was then being thrown as the TagBuilder did not contain an id.

Anyway the way around the problem was to implement a simple View Model instead of setting the Model to be a collection directly so that Dogs was a property on the model and therefore the modelName used to generate the id becomes "Dogs[0].Name" which works.


I think the problem maybe with the names... i mean since you are using -

<%: Html.TextBoxFor(m => Model[i].Name)%>
 <%: Html.ValidationMessageFor(m => Model[i].Name)%>

i cant test out right now but this might work-

<%: Html.Label("Name",Model[i].Name) %>
<%: Html.TextBox("Name", Model[i].Name)%>
<%: Html.ValidationMessage("Name",Model[i].Name)%>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜