3

Phil Haack has an article that describes how to set things up so the default model binder will bind to a collection on a post back:

http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

The problem I am having is I am not just trying to send a collection back to the Controller action, but a ViewModel with a collection.

I have a class that basically looks like this:

public class MyViewModel
{
public int IncidentNumber { get; set; }
public string StoreId { get; set; }
public string RepId { get; set; }
public string OrderStatus { get; set; }
public CustomerViewModel Customer { get; set;
//... other properties and SelectLists for binding

public IEnumerable<OrderItemViewModel> OrderItemViewModels { get; set; }

I can actually get the CustomerViewModel data back on a postback, but the list of OrderItemViewModels is empty. How do I get those back? Phil's article isn't helping there.

Chris Holmes
  • 11,444
  • 12
  • 50
  • 64

2 Answers2

5

I had a similar problem here MVC binding to model with list property ignores other properties which was solved by using the following code within the view

<div class="editor-field">
@for (int i = 0; i < Model.MyCollection.Count(); i++)
{
    @Html.HiddenFor(m => m.MyCollection[i].Id)
    @Html.HiddenFor(m => m.MyCollection[i].ParentId)
    @Html.HiddenFor(m => m.MyCollection[i].Name)
    @Html.TextBoxFor(m => m.MyCollection[i].Value)
}
</div>
Community
  • 1
  • 1
robmzd
  • 1,813
  • 3
  • 20
  • 37
  • 1
    I am giving you the thumbs up on this because it's essentially the right answer. What it comes down to, I learned, is the Name property on the HTML Input element. It has to be in a certain format (as that other thread showed) in order for the model binder to figure it out. And your particular answer is correct (I had to deal with DropDown boxes and had to manually override the Name property to get this to work) – Chris Holmes Nov 08 '11 at 23:18
  • Thank you! Took me way too long to find this answer, I hope more people +1 it. – jhilden Feb 05 '13 at 21:34
1

Use an editor template:

@model MyViewModel
@using (Html.BeginForm())
{
    ... some input fields 

    @Html.EditorFor(x => x.OrderItemViewModels)

    <input type="submit" value="OK" />
}

and then inside the corresponding editor template which will automatically be rendered for each element of the OrderItemViewModels collection (~/Views/Shared/EditorTemplates/OrderItemViewModels.cshtml):

@model OrderItemViewModels
<div>
    @Html.LabelFor(x => x.Prop1)
    @Html.EditorForFor(x => x.Prop1)
</div>
<div>
    @Html.LabelFor(x => x.Prop2)
    @Html.EditorForFor(x => x.Prop2)
</div>
...
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Darin, This doesn't quite work because the naming on the individual items doesn't get built right for the data to get bound to the parameters. – Chris Holmes Nov 08 '11 at 21:15