Note that there are some explanatory texts on larger screens.

plurals
  1. POASP.NET MVC Model Binding Related Entities on Same Page
    primarykey
    data
    text
    <p>This problem has been driving me crazy for several hours now...</p> <p>In my domain, I have 2 entities that are related to each other <code>Sku</code> and <code>Item</code>. Each sku can have many items.</p> <pre><code>public class Sku { private readonly EntitySet&lt;Item&gt; items; public Sku() { items = new EntitySet&lt;Item&gt;(AttachItems, DetachItems); } public int SkuId { get; set; } public string LongDescription { get; set; } public EntitySet&lt;Item&gt; Items { get { return items; } set{ items.Assign(value);} } private void AttachItems(Item entity) { entity.Sku = this; } private static void DetachItems(Item entity) { entity.Sku = null; } } public class Item { public Sku Sku { get; set; } public int ItemId { get; set; } public string Category { get; set; } public string Description { get; set; } } </code></pre> <p>I am building a page that will allow the end-user to update some fields on the sku and some fields on each item at the same time.</p> <pre><code>&lt;% using (Html.BeginForm("Save", "Merchant", FormMethod.Post, new { enctype = "multipart/form-data" })) { %&gt; &lt;fieldset&gt; &lt;legend&gt;Sku&lt;/legend&gt; &lt;p&gt;&lt;label for="SkuId"&gt;SkuId:&lt;/label&gt; &lt;%= Html.TextBox("SkuId", Model.SkuId, new{@readonly="readonly",onfocus="this.blur();"}) %&gt;&lt;/p&gt; &lt;p&gt;&lt;label for="LongDescription"&gt;LongDescription:&lt;/label&gt; &lt;%= Html.TextBox("LongDescription", Model.LongDescription) %&gt;&lt;/p&gt; &lt;/fieldset&gt; &lt;% for (int i = 0; i &lt; Model.Items.Count; i++) { %&gt; &lt;fieldset&gt; &lt;legend&gt;Item&lt;/legend&gt; &lt;p&gt;&lt;label for="ItemId"&gt;ItemId:&lt;/label&gt; &lt;%= Html.TextBox(string.Format("items[{0}].{1}", i, "ItemId"), Model.Items[i].ItemId, new { @readonly = "readonly", onfocus = "this.blur();" })%&gt;&lt;/p&gt; &lt;p&gt;&lt;label for="Category"&gt;Category:&lt;/label&gt; &lt;%= Html.TextBox(string.Format("items[{0}].{1}", i, "Category"), Model.Items[i].Category)%&gt;&lt;/p&gt; &lt;p&gt;&lt;label for="Description"&gt;Description:&lt;/label&gt; &lt;%= Html.TextBox(string.Format("items[{0}].{1}", i, "Description"), Model.Items[i].Description)%&gt;&lt;/p&gt; &lt;/fieldset&gt; &lt;%} // for-loop %&gt; &lt;p&gt;&lt;input type="submit" value="Save" /&gt;&lt;/p&gt; &lt;%} // form %&gt; </code></pre> <p>I have some controller code that works by accepting both a <code>Sku</code> and an <code>EntitySet</code> of <code>Item</code> and then assigning the <code>Items</code> to the <code>Sku</code>.</p> <pre><code> [AcceptVerbs(HttpVerbs.Post)] public ActionResult Save(Sku sku, EntitySet&lt;Item&gt; items) { if (sku != null) { if (items != null) { sku.Items.Assign(items); } } // save Sku to repository ... // return Details view ... } </code></pre> <p>This works, however I have noticed that it makes two trips through the <code>DefaultModelBinder</code> for each <code>Item</code> in addition to one trip for the <code>Sku</code>. When the <code>Sku</code> is bound, the setter for <code>Items</code> is called, and the binder even passes in a hydrated <code>Items</code> collection with the correct values. However, after the call to <code>items.Assign</code>, <code>Items.Count</code> is <code>0</code>. This is why I have to re-assign the items in the controller code. I was expecting the items to be transferred over to the <code>Items</code> collection by the binder. This should eliminate the extra trip per item, since the <code>items</code> parameter on my controller method could be removed. Why isn’t this working?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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