How to apply validation to a collection item in Asp.net MVC 2http://forums.asp.net/t/1800271.aspx/1?How+to+apply+validation+to+a+collection+item+in+Asp+net+MVC+2Sun, 06 May 2012 07:11:05 -040018002714966197http://forums.asp.net/p/1800271/4966197.aspx/1?How+to+apply+validation+to+a+collection+item+in+Asp+net+MVC+2How to apply validation to a collection item in Asp.net MVC 2 <p>I have a strongly typed view, which has some input boxes to map to a collection in an entity. Say for an example , take case of a View for adding an Employee detail and within that there are input fields to enter department name as well (say 2). Both of them are required. <br> <br> <br> Here is the class structure of these two entities:<br> <br> &nbsp;</p> <pre class="prettyprint">public class Employee { public int EmployeeID{get;set;} public string Name {get;set; } public IList&lt;Department&gt; DepartmentList{get;set;} } public class Deparment { public string Name {get;set; } public int ID { get;set; } } &lt;input type='text' class='input-choice' id='txtChoice0' name='Department[0].Name' /&gt;</pre> <p><br> <br> <br> Now my question is how should I apply validation to this. I have marked Required Attribute over the department collection in the Employee class and as well as on the field level in Department object, but nothing works.<br> <br> Any ideas ??<br> <br> <br> </p> 2012-05-04T19:09:37-04:004966285http://forums.asp.net/p/1800271/4966285.aspx/1?Re+How+to+apply+validation+to+a+collection+item+in+Asp+net+MVC+2Re: How to apply validation to a collection item in Asp.net MVC 2 <p>Have you tried adding data annotations to the Department class' properties?</p> <p>[Required]<br> public string Name { get;set }</p> <p>Then you can tuck your code inside an if (ModelState.IsValid) { ... } conditional</p> <p>Just remember that it validates against the model you pass to your ActionResult.</p> 2012-05-04T20:11:33-04:004966291http://forums.asp.net/p/1800271/4966291.aspx/1?Re+How+to+apply+validation+to+a+collection+item+in+Asp+net+MVC+2Re: How to apply validation to a collection item in Asp.net MVC 2 <p>Yes that is already done, but client side validation fails to run...</p> <p>Also, my Markup for the input field and the associated validation is like this&nbsp; :</p> <p>&nbsp;&lt;input type='text' class='input-choice' id='txtChoice0' name='DepartmentList[0].Name' /&gt; &lt;%=Html.ValidationMessage(&quot;DepartmentList[0].Name&quot;) %&gt;</p> <p>Model binding works perfectly fine, so I do see that the name 'DepartmentList[0].Name' in the input field maps correctly to the collection property in the Employee object in the controller and then I thought same way my validations will work but they don't get fired at all</p> <p></p> 2012-05-04T20:20:23-04:004966328http://forums.asp.net/p/1800271/4966328.aspx/1?Re+How+to+apply+validation+to+a+collection+item+in+Asp+net+MVC+2Re: How to apply validation to a collection item in Asp.net MVC 2 <p>Edit -- I was <a href="https://forums.asp.net/post/4966391.aspx">incorrect</a> in my original statement.</p> <p>You can still implemenet implement <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.ivalidatableobject.aspx"> IValidatableObject</a> for custom validation in your model.</p> <p></p> <p></p> 2012-05-04T21:21:10-04:004966333http://forums.asp.net/p/1800271/4966333.aspx/1?Re+How+to+apply+validation+to+a+collection+item+in+Asp+net+MVC+2Re: How to apply validation to a collection item in Asp.net MVC 2 <p></p> <blockquote><span class="icon-blockquote"></span> <h4>BrockAllen</h4> <p></p> <p>Since validation doesn't recurse on the model, consider having your top model (Employee in this case) implement <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.ivalidatableobject.aspx"> IValidatableObject</a>. It can then check the validation of its child objects and report it back up to MVC.</p> <p></p> <p></p> </blockquote> <p></p> <p>Isn't this part of .NET framwork 4.5 . I am using .NET version 4.0 and MVC 2 ??</p> 2012-05-04T21:26:22-04:004966337http://forums.asp.net/p/1800271/4966337.aspx/1?Re+How+to+apply+validation+to+a+collection+item+in+Asp+net+MVC+2Re: How to apply validation to a collection item in Asp.net MVC 2 <p>It's in .NET 4. If you're still in MVC2/.NET3.5, then you can implement <a href="http://www.asp.net/mvc/tutorials/older-versions/models-%28data%29/validating-with-the-idataerrorinfo-interface-cs"> IDataErrorInfo</a>.</p> 2012-05-04T21:29:01-04:004966381http://forums.asp.net/p/1800271/4966381.aspx/1?Re+How+to+apply+validation+to+a+collection+item+in+Asp+net+MVC+2Re: How to apply validation to a collection item in Asp.net MVC 2 Collection is not the problem!!! Client side validation needs html5 attributes that translates the conditions of the validation attributes. Such validation attributes are added by the html helpers like Html.TextboxFor...if you write simply &lt;input......no attributes are created and clint side validation doesnt work. 2012-05-04T23:07:21-04:004966384http://forums.asp.net/p/1800271/4966384.aspx/1?Re+How+to+apply+validation+to+a+collection+item+in+Asp+net+MVC+2Re: How to apply validation to a collection item in Asp.net MVC 2 <p></p> <blockquote><span class="icon-blockquote"></span> <h4>francesco abbruzzese</h4> Collection is not the problem!!! Client side validation needs html5 attributes that translates the conditions of the validation attributes. Such validation attributes are added by the html helpers like Html.TextboxFor...if you write simply &lt;input......no attributes are created and clint side validation doesnt work. </blockquote> <p></p> <p>Regardless if you have client side validation, he will always need server side validation and for nested object model binding the validation attributes on nested objects aren't honored.</p> 2012-05-04T23:12:36-04:004966387http://forums.asp.net/p/1800271/4966387.aspx/1?Re+How+to+apply+validation+to+a+collection+item+in+Asp+net+MVC+2Re: How to apply validation to a collection item in Asp.net MVC 2 Server side validation is pplied by the default model binder and since the drfault model binder is recursive it works ALSO for nested objects...hohrver all errors names are prefixed eith thr whole path ftom tje root model to the leaf property in error...if ...errors are not shown is becsusr thr right name convrntion has not been respected 2012-05-04T23:25:12-04:004966389http://forums.asp.net/p/1800271/4966389.aspx/1?Re+How+to+apply+validation+to+a+collection+item+in+Asp+net+MVC+2Re: How to apply validation to a collection item in Asp.net MVC 2 <p>I'll double check but I've not found this to be the case in my testing.</p> <p></p> 2012-05-04T23:27:00-04:004966391http://forums.asp.net/p/1800271/4966391.aspx/1?Re+How+to+apply+validation+to+a+collection+item+in+Asp+net+MVC+2Re: How to apply validation to a collection item in Asp.net MVC 2 <p></p> <blockquote><span class="icon-blockquote"></span> <h4>BrockAllen</h4> <p></p> <p>I'll double check but I've not found this to be the case in my testing.</p> <p></p> </blockquote> <p></p> <p>Ah yes, my mistake... my test was flawed.</p> <p>So back to the original poster, you can then easily apply the validation attributes to the nested class (as well as implement IDataErrorInfo for further validation as needed).</p> <p></p> 2012-05-04T23:30:06-04:004966783http://forums.asp.net/p/1800271/4966783.aspx/1?Re+How+to+apply+validation+to+a+collection+item+in+Asp+net+MVC+2Re: How to apply validation to a collection item in Asp.net MVC 2 <p></p> <blockquote><span class="icon-blockquote"></span> <h4>BrockAllen</h4> Ah yes, my mistake... my test was flawed.</blockquote> <p></p> <p>It appears that also the more expert people have doubts on the exact way name convention are used in model binding and in error handling exactly....probably because there is pratically no documentation on the subject... I will write asap a blog post about name conventions and prefix handling in my blog(there are already 2 posts scheduled, so maybe it will apeear in about 1 month).&nbsp;</p> 2012-05-05T08:54:12-04:004967008http://forums.asp.net/p/1800271/4967008.aspx/1?Re+How+to+apply+validation+to+a+collection+item+in+Asp+net+MVC+2Re: How to apply validation to a collection item in Asp.net MVC 2 <p>No, nested model binding I am fine with -- I just made a mistake on my test. I had never tried to put validation attributes on the nested classes to see if validation also flowed (or I had forgotten).</p> <p>So I used this test code:</p> <pre class="prettyprint">public class Baz { [Required] public string Quux { get; set; } } public class Foo { [Required] public string Bar { get; set; } public Baz Baz { get; set; } } public class HomeController : Controller { public ActionResult Index(Foo foo) { var v = ModelState.IsValid; return View(); } }</pre> <p><br />And when I tested I used:</p> <p><br />/Home/Index?foo.Bar=1&amp;foo.Baz.Quux=2 // IsValid == true</p> <p>/Home/Index?foo.Bar=1 // IsValid == true</p> <p>The 2nd query string is where I was mislead -- I should have used:</p> <p>/Home/Index?foo.Bar=1&amp;foo.Baz.Quux= // IsValid == false</p> <p>And then I could have also changed the code:</p> <pre class="prettyprint"> public class Baz { [Required] public string Quux { get; set; } } public class Foo { [Required] public string Bar { get; set; } [Required] public Baz Baz { get; set; } } public class HomeController : Controller { public ActionResult Index(Foo foo) { var v = ModelState.IsValid; return View(); } }</pre> <p><br> And now with this change:</p> <p>/Home/Index?foo.Bar=1 // IsValid == false</p> <p></p> <p>So yea, I was hasty in my test :/</p> 2012-05-05T13:42:11-04:004967219http://forums.asp.net/p/1800271/4967219.aspx/1?Re+How+to+apply+validation+to+a+collection+item+in+Asp+net+MVC+2Re: How to apply validation to a collection item in Asp.net MVC 2 <p></p> <blockquote><span class="icon-blockquote"></span> <h4>BrockAllen</h4> No, nested model binding I am fine with -- I just made a mistake on my test. I had never tried to put validation attributes on the nested classes to see if validation also flowed (or I had forgotten).</blockquote> <p></p> <p>No doubt you know the name conventions for nested model binding. In general, after one starts playing with more complex models or with lists...one master these rules.</p> <p>HOWEVER, there a lot of small ..things related to them, that in some circumstances becomes very important, such as:</p> <ol> <li>The way prefixes are handled by several parts of the system. As a default a lot of routines adds prefixes to the names...some Rendering helpers do it some others...do not. Errors handling routines also ...handles automatically prefixes...most of the times...:) </li><li>Smart ways to &quot;adjust&quot; prefixes(smart means...while continuing to use the ...TextBoxFor..and similar helpers) prefixes when the action method where we post has a &nbsp; model that is different from the rendering model. </li><li>What happens exactly when an action method has several parameters that are complex objects ...in this cases the names of the parameters may cause problems...unluckly such problems appears also when we have just one parameter...and we don't care its name because we want to bind simply the parameter properties. </li><li>Does the TextBox and TextBoxFor do the same &quot;stuff&quot;? I mean if we use string expressions instead of lambda expressions can we substitute TextBoxFor with TextBox ? This is usefull when we have to post to a different model....unlukly the general answer is NO!!! We cant substitute them...the risk is that some metadata are not computed with TextBox...and similar...because the Metadata retrieving functions for lambda and string expressions works differently....If the model is not nested they are equivalent...but in other cases they are not </li><li>How does validation summary and ValidationMessageFor use nested expression string in determinin their behaviour?... </li><li>When we define a custom Validation attribute...like the CompareAttribute that depends also on another property..are there limitations to the &quot;other property&quot; in case of nested models?....UNLUCLY THERE ARE LIMITATIONS....that however can be overcome with some tricks.... </li><li>How to handle collections with multiple indices(multidimensional arrays)? </li></ol> <p>.......And the list continue...</p> <p>Does everyone has an answer to all aboveproblems?&nbsp;(and to several other name convention related problems)&nbsp;</p> <p>I discovered all this problems while implementing &quot;tools&quot; that forced me to study the sources....However I noticed that most of people don't know such stuffs probably because most of the above problems are nopt clearly stated in some place...(there is something in this forum...and in stackoverflow...).....however when the problem is &quot;hit&quot; they go crazy because some &quot;stuffs&quot; are not so easy to imagine</p> <p></p> 2012-05-05T19:14:59-04:004967269http://forums.asp.net/p/1800271/4967269.aspx/1?Re+How+to+apply+validation+to+a+collection+item+in+Asp+net+MVC+2Re: How to apply validation to a collection item in Asp.net MVC 2 <p></p> <blockquote><span class="icon-blockquote"></span> <h4>francesco abbruzzese</h4> Server side validation is pplied by the default model binder and since the drfault model binder is recursive it works ALSO for nested objects...hohrver all errors names are prefixed eith thr whole path ftom tje root model to the leaf property in error...if ...errors are not shown is becsusr thr right name convrntion has not been respected </blockquote> <p></p> <p></p> <p>Honestly , I am more confused now. So do you mean the problem is with the naming convention of the validation helper that I have used.</p> <p>?? </p> <p>I am using &lt;%=Html.ValidationMessage(&quot;Department[0].Name&quot;) %&gt; after the first input. If I also pass on the error message along with the model name , error message&nbsp; appears right away on the view load</p> <p><br> Model binding on other hand is working perfectly fine, I get both Parent and its child(collection of child in fact) in the controller.</p> <p>Also , I thought MVC will have a very straighforward approach for applying validation to cotrols representing child collection. My only requirement is that I need to add Parent and child together in a single view.</p> <p>I do not have much exp in MVC so don't know if my following the right approach or not.</p> 2012-05-05T21:27:55-04:004967451http://forums.asp.net/p/1800271/4967451.aspx/1?Re+How+to+apply+validation+to+a+collection+item+in+Asp+net+MVC+2Re: How to apply validation to a collection item in Asp.net MVC 2 <p></p> <blockquote><span class="icon-blockquote"></span> <h4>kunal1982</h4> So do you mean the problem is with the naming convention of the validation helper that I have used.</blockquote> <p></p> <p>No my answer was for Brock that asserted that the problkem was the nameing convention. However, my general observation apply also to your problem. &quot;Most of people have not very clear the role of naming conventions&quot;. In your case the name convention is ok. However the name conventione ALONE is not enough for the client side validation to work.&nbsp;</p> <p>You used ValidationMessage to apply error but this is not enough. ValidationMassage is just a container where to write the error. The actual error is handled by the input field. Now you wrote simply &lt;input....that is you have not used the Html helpers for that field. Also if you apply the right name convention this is not enough for client side valdation to work. In fact when you call TextBox or TextBoxFor they creat an &lt;input....with the right name convention AND ALSO add them some Html5 data- .... attributes with informations about the client side validation rule to apply. If you want to write &lt;input....manually you MUST write yourself MANUALLY this information. I hope now everything is clear VALIDATION ERROR INFORMATION ARE NOT STORED IN ValidationMessage BUT IN THE INPUT FIELDS.&nbsp;</p> 2012-05-06T07:11:05-04:00