I'm getting myself acquainted with ASP.NET MVC but i'm running into something probably trivial. I have a model called ToDoList, this is a complex type with a list of ToDoItems:
public class ToDoList
{
public Guid Id {get;set;}
public string Name { get; set; }
public virtual ICollection<ToDoItem> Items {get;set;}
}
public class ToDoItem
{
public int Id { get; set; }
public string Task { get; set; }
public bool IsDone { get; set; }
public virtual ToDoList ToDoList { get; set; }
}
My Details page with form looks like this:
@model DataLayer.TomTest.Entities.ToDoList
<h2>@Model.Name</h2>
@using (@Html.BeginForm())
{
@Html.AntiForgeryToken()
<table>
<tr>
<th>
@Html.DisplayNameFor(model => model.Items.First().Id)
</th>
<th>
@Html.DisplayNameFor(model => model.Items.First().Task)
</th>
<th>
@Html.DisplayNameFor(model => model.Items.First().IsDone)
</th>
</tr>
@foreach (var toDoItem in Model.Items)
{
<tr>
<td>
@toDoItem.Id
</td>
<td>
@Html.EditorFor(model => toDoItem.Task)
</td>
<td>
@Html.EditorFor(model => toDoItem.IsDone, new {htmlAttributes = new {@Style = "margin-left: 10px;"}})
</td>
</tr>
}
</table>
<input type="submit" value="Save" />
}
And this is the method it posts to:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Details([Bind(Include = "Id,Name,Items")] ToDoList todoList)
{
if (ModelState.IsValid)
{
_context.Entry(todoList).State = EntityState.Modified;
await _context.SaveChangesAsync();
return View();
}
return View();
}
As you can see I included the [Bind] attribute as I read somewhere that would ensure i get the correct properties passed. When I debug this however, only the Id property is filled the rest remains null.
What can I do to fix this? Is it a mistake in the View? Or is it possible Entity Framework isn't setup correctly? Thanks in advance for your help.
CodePudding user response:
Model binding to a list doesn't work with a foreach; you need to use a for loop instead.
You'll also need hidden inputs for any properties which don't have editors within the loop.
@for (int index = 0; index < Model.Items.Count; index )
{
<tr>
<td>
@Html.HiddenFor(m => m.Items[index].Id)
@Model.Items[index].Id
</td>
<td>
@Html.EditorFor(m => m.Items[index].Task)
</td>
<td>
@Html.EditorFor(m => m.Items[index].IsDone, new { htmlAttributes = new { @Style = "margin-left: 10px;" } })
</td>
</tr>
}

