Scenario
- Client is the parent record
- A client can have one or more contacts
- Contact is the child record
Models
Parent Record
public class ClientModel{
// Parent Record - Attributes
// Db-wise: Id is the primary key,
// serves as foreign key for child records
public int Id { get; set; }
public string ClientName { get; set; }
// Child Records
public List<ContactModel> Contacts { get; set; }
public ClientModel()
{
Contacts = new List<ContactModel>();
}
}
Child Record
public class ContactModel{
// Each child record has a temporary unique id to facilitate binding
public ContactModel()
{
this.GUID = Guid.NewGuid().ToString();
}
// Helper to form control id.
// e.g. [50e32e2b-a9af-45ec-8be5-97ffa219dae8].FirstName
public string ControlId(string controlName)
{
return string.Format("[{0}].{1}", this.GUID, controlName);
}
public string GUID { get; set; }
// Attributes of child record
// Db-wise: Foreign key is the Client Id
// Primary key is auto generated id
public string FirstName { get; set; }
public string LastName { get; set; }
}
Views
Client.cshtml
@using MvcMultipleItemDataBinding.Models@model ClientModel
@{
ViewBag.Title = "Client";
}
<h2>Client</h2>
@using (Html.BeginForm())
{
@Html.HiddenFor(m => m.Id)
@Html.LabelFor(model => model.ClientName)
@Html.TextBoxFor(model => model.ClientName)
<h3>Contacts</h3>
<table>
<thead>
<tr>
<td>First Name</td>
<td>Last Name</td>
</tr>
</thead>
<tbody>
@foreach (var contact in Model.Contacts)
{
@Html.Partial("_Contacts", contact);
}
</tbody>
</table>
<input type="submit" value="Submit" />
}
_Contacts.cshtml
@using MvcMultipleItemDataBinding.Models@model ContactModel
<tr>
<td>
@*index of one of the items in the array of items*@
@*index.value = 50e32e2b-a9af-45ec-8be5-97ffa219dae8*@
@Html.Hidden(name: "index", value: @Model.GUID)
@*e.g. [50e32e2b-a9af-45ec-8be5-97ffa219dae8].FirstName*@
@Html.TextBox(@Model.ControlId("FirstName"), Model.FirstName)
</td>
<td>@Html.TextBox(@Model.ControlId("LastName"), Model.LastName)</td>
</tr>
Controller Actions
[HttpGet]
public ActionResult Client()
{
var model = new ClientModel();
// Display 2 blank rows
model.Contacts.Add(new ContactModel());
model.Contacts.Add(new ContactModel());
return View(model);
}
[HttpPost]
public ActionResult Client(ClientModel model)
{
TryUpdateModel(model.Contacts);
return View(model);
}