title: Modelbinder creates new instance of collection item instead of updating existing
body: <p>I want to create a dynamic form based on content from a CMS. The label of my fields (and also many more properties) will be generated in the CMS. To illustrate I statically create the view model within the controller GET action. With a custom model binder I will create the same structure of the view model for POST action.</p>
  
  <p>Here are view models:</p>
  
  <pre><code>[ModelBinder(typeof(TestModelBinder))]
  public class TestViewModel
  {
      public TestViewModel()
      {
          this.Fields = new List&lt;FieldViewModel&gt;();
      }
  
      public string Title { get; set; }
  
      public IList&lt;FieldViewModel&gt; Fields { get; private set; } 
  }
  
  public class FieldViewModel
  {
      public FieldViewModel(string label)
      {
          this.Label = label;
      }
  
      public string Label { get; set; }
  
      public string Value { get; set; }
  }
  </code></pre>
  
  <p>The index view:</p>
  
  <pre><code>@model Website.Models.TestViewModel
  
  &lt;h1&gt;Title: @Model.Title&lt;/h1&gt;
  
  @using (Html.BeginForm())
  {
      for (int i = 0; i &lt; Model.Fields.Count; i++)
      {
          @Html.Partial("Field", Model.Fields[i], new ViewDataDictionary(ViewData)
                      {
                          TemplateInfo = new TemplateInfo
                          {
                              HtmlFieldPrefix = string.Format("Fields[{0}]", i)
                          }
                      })
      }
  
      &lt;input type="submit" value="submit" /&gt;
  }
  </code></pre>
  
  <p>The partial view for the fields:</p>
  
  <pre><code>@model Website.Models.FieldViewModel
  
  @Html.LabelFor(model =&gt; model.Value, Model.Label)
  @Html.TextBoxFor(model =&gt; model.Value)
  </code></pre>
  
  <p>The controller:</p>
  
  <pre><code>public ActionResult Index()
  {
      var model = new TestViewModel { Title = "GET action" };
      model.Fields.Add(new FieldViewModel("Name"));
      model.Fields.Add(new FieldViewModel("E-Mail"));
  
      return View(model);
  }
  
  [HttpPost]
  public ActionResult Index(TestViewModel model)
  {
      return View(model);
  }
  </code></pre>
  
  <p>And my model binder:</p>
  
  <pre><code>public class TestModelBinder : System.Web.Mvc.DefaultModelBinder
  {
      protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
      {
          var model = new TestViewModel { Title = "POST action" };
          model.Fields.Add(new FieldViewModel("Name"));
          model.Fields.Add(new FieldViewModel("E-Mail"));
          return model;
      }
  }
  </code></pre>
  
  <p>The GET action works as expected. But I have a problem while binding the model. After posting the form, I get the following error:</p>
  
  <pre><code>No parameterless constructor defined for this object.
  </code></pre>
  
  <p>Stack Strace:</p>
  
  <pre><code>[MissingMethodException: No parameterless constructor defined for this object.]
     System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean&amp; canBeCached, RuntimeMethodHandleInternal&amp; ctor, Boolean&amp; bNeedSecurityCheck) +0
     System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark&amp; stackMark) +159
     System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark&amp; stackMark) +256
     System.Activator.CreateInstance(Type type, Boolean nonPublic) +127
     System.Activator.CreateInstance(Type type) +11
     System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +275
  
  [MissingMethodException: No parameterless constructor defined for this object. Object type 'Website.Models.FieldViewModel'.]
     System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +370
     System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +151
     System.Web.Mvc.DefaultModelBinder.UpdateCollection(ControllerContext controllerContext, ModelBindingContext bindingContext, Type elementType) +569
     System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +974
     System.Web.Mvc.DefaultModelBinder.GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) +33
     System.Web.Mvc.DefaultModelBinder.BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) +441
     System.Web.Mvc.DefaultModelBinder.BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) +180
     System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model) +68
     System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +997
     System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +437
     System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +153
     System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +642
  </code></pre>
  
  <p>As the error message say, this is because <code>FieldViewModel</code> doesn't have a default constructor. But says also, that the <code>DefaultModelBinder</code> tries to create a new instance of a <code>FieldViewModel</code>? This feels weird, because I have created my model instance and filled the <code>Fields</code> list with 2 instances of <code>FieldViewModel</code> and I would expect that the model binder updates the existing instances instead of creating new ones...</p>
  
  <p>After digging into the <code>DefaultModelBinder</code> I found the following line of code within the <code>UpdateCollection</code> while creating the <code>innerContext</code>:</p>
  
  <pre><code>ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, elementType)
  </code></pre>
  
  <p>If this line would look something like this, I think it would work:</p>
  
  <pre><code>ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(existingCollectionElement, elementType)
  </code></pre>
  
  <p>Is this the expected behavior? What can I do to get rid of this and use my existing instance within the collection? Overriding this seems not a good option, because this code is internal and I would copy many code, for this simple line. Is there maybe another way of doing what I want or am I doing something wrong?</p>
  
  <p><strong>Update:</strong> It is not a problem of the binding itself. When I would remove my constructor from <code>FieldViewModel</code>, then the posted values are correctly added into the <code>Value</code> property of the view models. The problem is, that the label property will be empty (because it creates a new instance and not take the one I've created in the custom modelbinder) and will be set to "Value" in both fields. At the end, the <code>FieldViewModel</code> should also implement the <code>IValidatableObject</code> interface and should be validated by the <code>DefaultModelBinder</code>. The available validators for each field is also defined in the CMS and will be added to the view model instance in the custom model binder. So also this case won't work actually because all added validators will be lost.</p>