Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do you validate individual collection items in an ASP.NET MVC complex Entity Framework model?
    text
    copied!<blockquote> <p><strong>Possible Duplicate:</strong><br> <a href="https://stackoverflow.com/questions/5511386/mvc-clientside-validation-for-nested-collection-properties">mvc clientside validation for nested (collection) properties</a> </p> </blockquote> <p>I have a view displaying fields form a complex Entity Framework model with a few EntityCollection objects in it. They've proven to be very problematic because the Set method doesn't work during model binding, which is described (and my solution provided in the answers) in <a href="https://stackoverflow.com/questions/3577260/mvc2-rtm-model-binding-complex-objects-using-entity-framework">this stackoverflow question</a>. </p> <p>Now I'm having a problem with required field validation using the [Required] ValidationAttribute metadata on the TEntity type in the EntityCollection. I think it originated because when you use strongly typed Html Helpers for individual items in a collection like <code>Html.TextBoxFor(model =&gt; model.Application.References.ElementAt(i).FullName)</code> (where i is the int used in a for loop), the rendered output has an input with <code>name="FullName"</code> rather than <code>name="Application.References[0].FullName"</code>. That wasn't applying the metadata on the References class's properties at all. So my solution was to use the regular html helpers like so: <code>@Html.TextBox("Application.References[" + i + "].FullName", Model.Application.References.ElementAt(i).FullName)</code>.</p> <p>Now, only the server side validation created by the [Required] attributes works. The only way I can get client side validation is to manually add the data-val and data-val-required attributes to the rendered input as follows: <code>@Html.TextBox("Application.References[" + i + "].FullName", Model.Application.References.ElementAt(i).FullName, new { data_val="true", data_val_required="The Full Name for Reference " + i + " is required."})</code>. That seems like too much code-smell to me. Surely there's a better way to do this?</p> <p>Here are excerpts from my code for details:</p> <p><strong>EF Model</strong></p> <pre><code>public class Application { //...EF framework code... public EntityCollection&lt;Reference&gt; References { //get, set } } public partial class Reference : EntityObject { public global::System.String FullName { //get, set } } </code></pre> <p><strong>ReferenceMetaData.cs</strong></p> <pre><code>[MetadataType(typeof(ReferenceMetadata))] public partial class Reference { } public class ReferenceMetadata { [Required] [DisplayFormat(NullDisplayText = "N/A")] [DisplayName("Full Name")] public string FullName { get; set; } //...more properites } </code></pre> <p><strong>View</strong></p> <pre><code> @for (int i = 0; i &lt; 3; i++) { @Html.ValidationMessage("Application.References[" + i + "].FullName") &lt;div class="input-container"&gt; &lt;div class="editor-label"&gt; @Html.LabelFor(model =&gt; model.Application.References.ElementAt(i).FullName) &lt;/div&gt; &lt;div class="editor-field"&gt; @Html.TextBox("Application.References[" + i + "].FullName", Model.Application.References.ElementAt(i).FullName, new { maxlength = "100" }) &lt;/div&gt; &lt;/div&gt; @* more view code...*@ } </code></pre> <p>This code is without manually setting the data-val and data-val-required attributes on the @Html.TextBox. Adding that as follows enables client side validation, but at the cost of not sharing the same validation message as the default (or any I might specify in the <code>[Required(ErrorMessage = "Custom message")]</code> metadata):</p> <pre><code> @for (int i = 0; i &lt; 3; i++) { @Html.ValidationMessage("Application.References[" + i + "].FullName") &lt;div class="input-container"&gt; &lt;div class="editor-label"&gt; @Html.LabelFor(model =&gt; model.Application.References.ElementAt(i).FullName) &lt;/div&gt; &lt;div class="editor-field"&gt; @Html.TextBox("Application.References[" + i + "].FullName", Model.Application.References.ElementAt(i).FullName, new { maxlength = "100", data_val="true", data_val_required="The Full Name for Reference " + i + " is required." }) &lt;/div&gt; &lt;/div&gt; @* more view code...*@ } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload