Interaction with samples of nested collections in ASP.NET MVC

I am using the Steve Sanderson BeginCollectionItem helper with ASP.NET MVC 2 to model collection bindings if items.

This works fine until the collection item model contains another collection.

I have a model like this:

-Product
--Variants
--- IncludedAttributes

Whenever I visualize and model the binding of a Variants collection, it works jusst great. But with the help of the IncludedAttributes collection, I cannot use the BeginCollectionItem helper because the id and names value will not evaluate the id value and the names that parent Variant was created for it:

<div class="variant"> <input type="hidden" value="bbd4fdd4-fa22-49f9-8a5e-3ff7e2942126" autocomplete="off" name="Variants.index"> <input type="hidden" value="0" name="Variants[bbd4fdd4-fa22-49f9-8a5e-3ff7e2942126].SlotAmount" id="Variants_bbd4fdd4-fa22-49f9-8a5e-3ff7e2942126__SlotAmount"> <table class="included-attributes"> <input type="hidden" value="0" name="Variants.IncludedAttributes[c5989db5-b1e1-485b-b09d-a9e50dd1d2cb].Id" id="Variants_IncludedAttributes_c5989db5-b1e1-485b-b09d-a9e50dd1d2cb__Id" class="attribute-id"> <tr> <td> <input type="hidden" value="0" name="Variants.IncludedAttributes[c5989db5-b1e1-485b-b09d-a9e50dd1d2cb].Id" id="Variants_IncludedAttributes_c5989db5-b1e1-485b-b09d-a9e50dd1d2cb__Id" class="attribute-id"> </td> </tr> </table> </div> 

If you look at the name of the first hidden field inside the table, this is Variants.IncludedAttributes - where the options should have been [bbd4fdd4-fa22-49f9-8a5e-3ff7e2942126] .IncludedAttributes [...] ...

This is because when I call BeginCollectionItem for the second time (in the IncludedAttributes collection), there is no information about the index of the item element of this parent variant.

My Variant rendering code looks like this:

 <div class="product-variant round-content-box grid_6" data-id="<%: Model.AttributeType.Id %>"> <h2><%: Model.AttributeType.AttributeTypeName %></h2> <div class="box-content"> <% using (Html.BeginCollectionItem("Variants")) { %> <div class="slot-amount"> <label class="inline" for="slotAmountSelectList"><%: Text.amountOfThisVariant %>:</label> <select id="slotAmountSelectList"><option value="1">1</option><option value="2">2</option></select> </div> <div class="add-values"> <label class="inline" for="txtProductAttributeSearch"><%: Text.addVariantItems %>:</label> <input type="text" id="txtProductAttributeSearch" class="product-attribute-search" /><span><%: Text.or %> <a class="select-from-list-link" href="#select-from-list" data-id="<%: Model.AttributeType.Id %>"><%: Text.selectFromList.ToLowerInvariant() %></a></span> <div class="clear"></div> </div> <%: Html.HiddenFor(m=>m.SlotAmount) %> <div class="included-attributes"> <table> <thead> <tr> <th><%: Text.name %></th> <th style="width: 80px;"><%: Text.price %></th> <th><%: Text.shipping %></th> <th style="width: 90px;"><%: Text.image %></th> </tr> </thead> <tbody> <% for (int i = 0; i < Model.IncludedAttributes.Count; i++) { %> <tr><%: Html.EditorFor(m => m.IncludedAttributes[i]) %></tr> <% } %> </tbody> </table> </div> <% } %> </div> </div> 

And the code for rendering includeAttribute:

 <% using (Html.BeginCollectionItem("Variants.IncludedAttributes")) { %> <td> <%: Model.AttributeName %> <%: Html.HiddenFor(m => m.Id, new { @class = "attribute-id" })%> <%: Html.HiddenFor(m => m.ProductAttributeTypeId) %> </td> <td><%: Model.Price.ToCurrencyString() %></td> <td><%: Html.DropDownListFor(m => m.RequiredShippingTypeId, AppData.GetShippingTypesSelectListItems(Model.RequiredShippingTypeId)) %></td> <td><%: Model.ImageId %></td> <% } %> 
+7
asp.net-mvc
source share
1 answer

Since you are using MVC 2 and EditorFor, you do not need to use the Steve solution, which I think just works for MVC 1. You should just do something like:

 <% for (int i = 0; i < Model.Variants.Count; i++) { %> <%= Html.DisplayFor(m => m.Variants[i].AttributeType.AttributeTypeName) %> <% for (int j = 0; j < Model.Variants[i].IncludedAttributes.Count; j++) { %> <%= Html.EditorFor(m => m.Variants[i].IncludedAttributes[j]) %> <% } %> <% } %> 

Note that using indexes ... [i] ... [j] ... is important, and how MVC will know how to correctly display IDs and names.

+6
source share

All Articles