Search code examples
asp.net-mvccheckboxfor

Binding IList to CheckBoxFor won't return checked values MVC


I'm trying to bind an IList to Html.CheckBoxFor.

When I first tried and investigated, I found that KeyValuePair won't do the job since its private nature, so I made a MyKeyValuePair. So now in my model I have:

public GameCreation()
    {
        Orientation = new List<MyKeyValuePair>();
        foreach (var v in Enum.GetNames(typeof(DeveloperPortalMVCApp.Models.Orientation)))
        {
            Orientation.Add(new MyKeyValuePair { Name = v });
        }
    }

    public MyKeyValuePair MyProperty { get; set; }
    public ObservableCollection<MyKeyValuePair> Orientation { get; set; }

My view is:

@Html.CheckBoxFor(model => model.MyProperty.Value)
                    @foreach (var f in Model.Orientation)
                    {
                        @Html.CheckBoxFor(model => f.Value)
                    }

The problems is that those MyKeyValuePair inside that IList won't update their value, but MyProperty will. What am I missing?


Solution

  • Use

    @Html.CheckBoxFor(model => model.MyProperty.Value)
    @for (var i=0; i < Model.Orientation.Count; i++)
    {
        @Html.CheckBoxFor(model => Model.Orientation[i].Value)
    }
    

    Pay special attention to the indexer, if you do not index the checkboxes, then you will end up with a bunch of checkboxes with conflicting names and or IDs. The model binder might be trying to bind this as a single item, not as a list.

    If you use the code sample above, you will get something similar to this:

    <input type="checkbox" name="Orientation[0].Value" />
    <input type="checkbox" name="Orientation[1].Value" />
    <input type="checkbox" name="Orientation[2].Value" />
    

    Which, the model binder can interpret as a list. If you don't use the indexer in the CheckBoxFor, then you will get something similar to this:

    <input type="checkbox" name="Orientation.Value" />
    <input type="checkbox" name="Orientation.Value" />
    <input type="checkbox" name="Orientation.Value" />
    

    And the modelbinder will not be able to make a list out of this.