title: Binding a List on POST with AJAX and FormData
body: <p>I'm attempting to bind a list of "Product Specifications" to my "Add Product" dialog. The submit is carried out with AJAX.</p>
  
  <p>Since I allow the user to upload a product image on this same form, I am sending my AJAX request with a 'FormData' object in lieu of serializing.</p>
  
  <p>The result is that the controller action is never reached due to the Specifications list not being in a format expected by the controller.</p>
  
  <h2>ProductModalViewModel</h2>
  
  <pre><code>public class ProductModalViewModel
  {
      public ProductModalViewModel()
      {
          Product = new Product();
          Specs = new List&lt;Spec&gt;();
      }
      public Product Product { get; set; }
  
      //Other properties removed for brevity
  
      public List&lt;Spec&gt; Specs { get; set; }
  }
  </code></pre>
  
  <h2>View (Modal)</h2>
  
  <pre><code>&lt;form id="formSaveProduct" onsubmit="SaveProduct(event)" enctype="multipart/form-data"&gt;
  
  &lt;input type="hidden" asp-for="Product.Id" /&gt;
  
  //Removed other form fields for brevity
  
  &lt;div class="specs-list-group"&gt;
      &lt;ul class="list-group"&gt;
          @for (int i = 0; i &lt; Model.Specs.Count(); i++)
          {
              &lt;li class="list-group-item"&gt;
                  &lt;input type="hidden" asp-for="@Model.Specs[i].Id" /&gt;
                  &lt;div class="row"&gt;
                      &lt;div class="col-5"&gt;
                          &lt;input type="text" asp-for="@Model.Specs[i].Name" /&gt;
                      &lt;/div&gt;
                      &lt;div class="col-5"&gt;
                          &lt;input type="text" asp-for="@Model.Specs[i].Value" /&gt;
                      &lt;/div&gt;
                  &lt;/div&gt;
              &lt;/li&gt;
          }
      &lt;/ul&gt;
  &lt;/div&gt;
  &lt;/form&gt;
  </code></pre>
  
  <h2>Script</h2>
  
  <pre><code>function SaveProduct(e) {
          e.preventDefault();  // prevent standard form submission
  
          $.ajax({
              url: "@Url.Action("SaveProduct", "ProductManagement", new { Area = "Admin" })",
              method: "post",
              data: new FormData($('#formSaveProduct')[0]),
              contentType: false,
              processData: false,
              success: function (result) {
                  if (result.success) {
                      $("#exampleModal").modal('toggle');
                      location.reload();
                  }
                  else {
                      $(".modal-body").html(result);
                  }
              },
              error: function (e) {
                  alert("Error: " + e.status)
              }
          });
      }
  </code></pre>
  
  <h2>Controller</h2>
  
  <pre><code> [HttpPost]
   public ActionResult SaveProduct(ProductModalViewModel model)
   {
       //Save
   }
  </code></pre>
  
  <h2>Request Header</h2>
  
  <pre><code>FormData:
  
  Product.Id: 1
  Product.Brand: Browning
  Product.Model: Gold Mossy Oak Shadow Grass Blades
  Product.ProductNum: 723654
  Product.CategoryId: 4
  Product.IsActive: true
  Product.Overview: This is an overview of the tkjsldfgn jlfdgl-sdfgn lkjgfnjkl dfsngkl kjlngkldf jngjkln kdfjnggf h sd sdfgdf...
  Specs[0].Id: 1
  Specs[0].Name: Test Spec 1
  Specs[0].Value: Test Value 1
  Specs[1].Id: 2
  Specs[1].Name: Test Spec 2
  Specs[1].Value: Test Value 2
  Specs[2].Id: 3
  Specs[2].Name: Test Spec 3
  Specs[2].Value: Test Value 3
  </code></pre>
  
  <p>This form works entirely fine until I add in the specifications list. What do I need to change to bind a list while using a FormData object?</p>
  
  <hr>
  
  <p>EDIT: Added Spec Entity for troubleshooting reference.</p>
  
  <pre><code>public class Spec
  {
      [Key]
      public int Id { get; set; }
  
      public Spec(string name, string value)
      {
          Name = name;
          Value = value;
      }
  
      [Required]
      public string Name { get; set; }
  
      [Required]
      public string Value { get; set; }
  
      [ForeignKey("Product")]
      [Required]
      public int ProductId {get; set; }
      public virtual Product Product { get; set; }
  
      //Timestamps
      public DateTime? Created { get; set; }
      public DateTime? Modified { get; set; }
  }
  </code></pre>