1

I'm having trouble binding a basic list of values to the model in my post action in the controller. The list is returning null.

I have a viewmodel which looks like this:

public class DistributionListFormModel : FormViewModel
{
    [Required(ErrorMessage = "The title is required")]
    public string Title { get; set; }

    public List<DistributionItem> DistributionItems { get; set; }
}

public class DistributionItem
{
    public string LabelText { get; set; }
    public bool Signup { get; set; }
}

Ok - so in my controller, I populate the DistributionItems list with some dud values within the index method. And here is a snapshot of my view:

<div class="o-wrapper">

@using (Html.BeginForm("Submit", "MyController", FormMethod.Post))
{
    foreach (var item in Model.DistributionItems)
     {
         <p>@item.LabelText</p>
         @Html.CheckBoxFor(m => item.Signup)

    }
    <button type="submit">SUBMIT</button>

}

Any idea why the DistributionItems list is null in the post controller? I found some articles but they all relate to very older versions of ASP.Net...

Thanks!!

James Wilkinson
  • 123
  • 1
  • 9

2 Answers2

1

This is one of those maddening things that exposes the limitations of model binding with lists in MVC.

What it comes down to is that you have to use a for loop with an indexer - a foreach loop won't work:

for (int i = 0; i < Model.DistributionItems.Count; i++)
{
     <p>@Model.DistributionsItems[i].LabelText</p>
     @Html.CheckBoxFor(m => m.DistributionsItems[i].Signup)
}

Here are a few references related to this that go into some more detail:

Model Binding to a List MVC 4

ASP.NET MVC 5 model binding list is empty

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

Eric Petroelje
  • 57,359
  • 8
  • 118
  • 174
  • Wow, two downvotes and no comments, did I miss something obviously wrong here? – Eric Petroelje Jul 26 '17 at 20:02
  • @Pat There is absolutely something wrong with using a `foreach`. The HTML helpers do not generate unique indices in the rendered HTML, which means the model binder is not able to determine how the elements should be associated when binding to a collection. – John H Jul 26 '17 at 20:06
  • @EricPetroelje No, your answer is correct. The reason I linked to the duplicate, though, is because people should understand how editor templates work, as they make this sort of situation so trivial to deal with. – John H Jul 26 '17 at 20:13
  • 2
    @JohnH - Yup, editor templates are the best way to handle this scenario. Just didn't want to introduce additional concepts that might cloud the core issue that the OP is having here. Added my close vote as well. – Eric Petroelje Jul 26 '17 at 20:18
  • That's fair enough - can definitely understand that point-of-view. – John H Jul 26 '17 at 20:20
  • 1
    Ah okay I see what you're saying, its only an issue with implicit binding then. Good to know -- I stand corrected – Pat Jul 26 '17 at 20:34
0

Have you tried doing this:

foreach (var item in Model)
{
    @Html.HiddenFor(model => item.LabelText )
    @Html.LabelFor(model=> item.LabelText )
    @Html.CheckBoxFor(model => item.Signup)
}

I've had this issue before and what's happening is your controller doesn't see the object. All you're returning is a list of boolean.

Ricky Sett
  • 59
  • 7