title: MVC CheckBox binding back to model
body: <p>so I've looked everywhere for an answer to this peculiar problem, but I couldn't find the exact solution. Lots of similar problems, but not one that solves my exact problem, so apologies if this has already been answered.</p>
  
  <p>I have the following (simplified) <strong>models</strong>:</p>
  
  <pre><code>public abstract class SimpleModel {
      public List&lt;SimpleFieldModel&gt; Fields{ get; set; }
  }
  
  public abstract class SimpleFieldModel {
      public List&lt;ListItemModel&gt; Items { get; set; }
  }
  
  public class ListItemModel {
       public string Text { get; set; }
       public string Value { get; set; }
       public bool Selected { get; set; }
  }
  </code></pre>
  
  <p>With the following <strong>SimpleModel View</strong>:</p>
  
  <pre><code>@for(var i = 0; i &lt; Model.Fields.Count; i++) {
      @Html.EditorFor(Model.Fields[i])
  }
  </code></pre>
  
  <p>And the following <strong>SimpleFieldModel View</strong>:</p>
  
  <pre><code>@for(var i = 0; i &lt; Model.Items.Count; i++) {
      @Html.CheckBoxFor(m =&gt; Model.Items[i].Selected)
      @Html.HiddenFor(m =&gt; Model.Items[i].Text)
  }
  </code></pre>
  
  <p>And this produces the expected <strong>markup</strong>:</p>
  
  <pre><code>&lt;input name="Fields[5].Items[0].Selected" id="Fields_5__Items_0__Selected" type="checkbox" value="true" data_val="89"&gt;
  &lt;input name="Fields[5].Items[0].Selected" type="hidden" value="false"&gt;
  &lt;input name="Fields[5].Items[0].Text" id="Fields_5__Items_0__Text" type="hidden" value="Option 1"&gt;
  </code></pre>
  
  <p>And when this is posted to the <strong>controller</strong>, I receive the following:</p>
  
  <ul>
  <li><strong>form-data</strong>: Fields[5].Items[0].Selected = "true,false"</li>
  <li><strong>model</strong>: Fields[5].Items[0].Selected = false</li>
  </ul>
  
  <p>I have had to write a method to populate my collection with the data from the form, but I feel that Razor should be taking care of this for me, but it doesn't seem to be working.</p>
  
  <h2>Edit</h2>
  
  <p>It would appear the root cause may be down to the fact I'm expecting to receive an abstract model into my controller, as so:</p>
  
  <pre><code>[HttpPost]
  [ValidateAntiForgeryToken]
  public ActionResult Edit(SimpleModel model)
  {
  }
  </code></pre>
  
  <p>To overcome this, I have the following <strong>model binder</strong>:</p>
  
  <pre><code>public class SimpleModelBinder : DefaultModelBinder
  {
      protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
      {
          var typeValue = bindingContext.ValueProvider.GetValue("ConcreteModelType");
          var type = Type.GetType(
              (string)typeValue.ConvertTo(typeof(string)),
              true
          );
          if (!typeof(SimpleModel).IsAssignableFrom(type))
          {
              throw new InvalidOperationException("Bad Type");
          }
          var model = Activator.CreateInstance(type);
          bindingContext.ModelMetadata = 
          ModelMetadataProviders.Current.GetMetadataForType(() =&gt; model, type);
  
          return model;
      }
  }
  </code></pre>
  
  <p>The strange thing though, is that at the point of exiting the above binder, the model has the correct number of Fields, and these each have their correct and expected Items. But, when I enter into the controller method, my model appears to have been altered, as it's now missing the Items from the Fields. </p>
  
  <p>I apologise for not including all code initially, but I cannot provide access to the full code-base.</p>
  
  <h2>Further Update</h2>
  
  <p>I think it might also be relevant to mention that I also have a <em>SimpleFieldModelBinder</em>. This is as so:</p>
  
  <pre><code>public class SimpleFieldModelBinder : DefaultModelBinder
  {
      protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
      {
          var typeValue = bindingContext.ValueProvider.GetValue(string.Format("{0}.{1}", bindingContext.ModelName, "ConcreteFieldModelType"));
          var type = Type.GetType(
              (string)typeValue.ConvertTo(typeof(string)),
              true
          );
          if (!typeof(SimpleFieldModel).IsAssignableFrom(type))
          {
              throw new InvalidOperationException("Bad Type");
          }
          var model = Activator.CreateInstance(type);
  
          bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() =&gt; model, type);
  
          return model;
      }
  }
  </code></pre>
  
  <p>So, when I exit the SimpleModelBinder, I have all my fields, and they have their correct Items in place (although unbound to recent form changes). Yet, my controller seems to be receiving a list of SimpleFieldModel objects which are missing their relevant Items list.</p>
  
  <p>Things are definitely going wrong with the SimpleFieldModelBinder. If I take it out, my <em>SimpleModel</em> contains a list of the abstract <em>SimpleFieldModel</em> objects. But, if I leave it in, the controller receives a <em>SimpleModel</em> with the correct concrete types inside its Fields list, but these are all cleared of their <em>Items</em>.</p>
  
  <h2>Another Update</h2>
  
  <p>I added some code in the SimpleFieldModelBinder, so that it populates the Items collection from the form data. On exiting the CreateModel, the collection was intact (and had the appropriate Selected values in place). Yet when I get to my controller (which I have to assume is the next step from binding?) These Items collections have been removed. One thing that's slightly suspicious though, is that the first Field <strong>has</strong> its Items in place, but all other fields do not. I suspect the binding is only working for the first item in the Fields collection, even though during debugging, I hit the SimpleFieldModelBinder for all the fields.</p>
  
  <p>What might I be missing?</p>
  
  <p>Thank you</p>