title: How to add items entered in a dynamic HTML table to a model-bound list
body: <p>I am using .NET CORE MVC for making some forms for the user to add people to a system (A manual process).  One of the forms I've got is a simple multi-add user form that allows the user to enter names on the form and click submit, where it is then serialized and converted into a PDF document to be saved to the local machine.</p>
  
  <p>I wanted to make this with a dynamic HTML Table in mind so I've got the following setup.  The intent here is to allow a table to start initially with a single empty, editable row and give the ability to add rows as they need, while binding each row to a list of objects on the model.</p>
  
  <p>User class   </p>
  
  <pre><code>    [Serializable]
      public class User
      {
          [Display(Name = "M.I.")]
          public string MiddleInitial { get; set; }
  
          [Display(Name = "Suffix")]
          public string NameSuffix { get; set; }
  
          [Required(AllowEmptyStrings = false)]
          [Display(Name = "First Name")]
          public string FirstName { get; set; }
  
          [Required(AllowEmptyStrings = false)]
          [Display(Name = "Last Name")]
          public string LastName { get; set; }
      }
  </code></pre>
  
  <p>MultiAddUser class</p>
  
  <pre><code>[Serializable]
  public class MultiAddUser
  {
      [Required]
      [Display(Name = "Start Date")]
      public DateTime StartDate { get; set; }
      public List&lt;User&gt; Users { get; set; }
  
      public MultiAddUser()
      {
          Users = new List&lt;User&gt;();
      }
  }
  </code></pre>
  
  <p>My view has the following code that displays the basic table with inputs in the cells with the ability to add cells on the fly.        </p>
  
  <pre><code>@using Contract
  @model MultiAddUser
  
  @section Scripts{
  
      &lt;script&gt;
          function addRow() {
              var table = document.getElementById("MultiAddUserTable");
              var row = table.insertRow(-1);
              var cell1 = row.insertCell(0);
              cell1.innerHTML = '&lt;input type="text" /&gt;';
              var cell2 = row.insertCell(1);
              cell2.innerHTML = '&lt;input type="text" /&gt;';
              var cell3 = row.insertCell(2);
              cell3.innerHTML = '&lt;input type="text" /&gt;';
              var cell4 = row.insertCell(3);
              cell4.innerHTML = '&lt;input type="text" /&gt;';
          }
      &lt;/script&gt;
  }
  
  &lt;style&gt;
      input {
          width: 100%;
      }
  &lt;/style&gt;
  
  &lt;body&gt;
      &lt;h2 class="formtitle"&gt;ADD MULTIPLE USERS&lt;/h2&gt;
      &lt;form method="post" asp-action="AddMultipleUsers" id="addMultiUsers"&gt;
          &lt;div class="form-group"&gt;
              &lt;div class="form-row"&gt;
                  &lt;div class="form-group col-sm-2"&gt;
                      &lt;label asp-for="StartDate"&gt;&lt;/label&gt;
                      &lt;input type="date" asp-for="StartDate" class="form-control" /&gt;
                      &lt;span asp-validation-for="StartDate" class="text-danger"&gt;&lt;/span&gt;
                  &lt;/div&gt;
              &lt;/div&gt;
  
              &lt;table id="AddMultipleUsersTable"&gt;
                  &lt;tr&gt;
                      &lt;th&gt;First Name&lt;/th&gt;
                      &lt;th&gt;Middle Initial&lt;/th&gt;
                      &lt;th&gt;Last Name&lt;/th&gt;
                      &lt;th&gt;Suffix&lt;/th&gt;
                  &lt;/tr&gt;
                  &lt;tr&gt;
                      &lt;td&gt;&lt;input type="text" /&gt;&lt;/td&gt;
                      &lt;td&gt;&lt;input type="text" /&gt;&lt;/td&gt;
                      &lt;td&gt;&lt;input type="text" /&gt;&lt;/td&gt;
                      &lt;td&gt;&lt;input type="text" /&gt;&lt;/td&gt;
                  &lt;/tr&gt;
              &lt;/table&gt;
  
              &lt;button type="button" onclick="addRow()"&gt;Add&lt;/button&gt;
  
              &lt;hr /&gt;
  
              &lt;div class="form-row"&gt;
                  &lt;div id="submitbutton"&gt;
                      &lt;input id="submit" class="btn btn-primary btn-lg" style="background-color: #4CAF50; color:white;" type="submit" /&gt;
              &lt;/div&gt;
      &lt;/form&gt;
  
  &lt;/body&gt;
  </code></pre>
  
  <p>Now normally with ASP.NET Core MVC you would just have something like <code>asp-for="@Model.Property[IndexIfNeeded]"</code> in the input tag helper but since the list starts empty and is not bound by a database, I'm having trouble piecing together how I would go about adding each new row as a new item to the list on the model once the entire form is submitted.</p>
  
  <p>I may be over complicating this since the data never needs to be entered into a database, but it does need to be serialized and converted into a PDF document and be printed at the end of the process so any insight as to alternative methods to accomplish that would be appreciated.</p>
  
  <p>In summary, <strong>How can I bind the rows / columns added dynamically to this table to my model objects, while maintaining validation rules on each required property?</strong></p>