My model is a simple parent/child representation looking like this
public class Parent
{
public int Id { get; set; }
public string Name { get; set; }
public List<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public string Name { get; set; }
}
Now, I want to create a page, which will allow me to edit/create children - one child at a time is just fine. I want to pass the parent into a view, create text box for Child.Name, collect whatever users types in and then save it into database.
So, in the first CreateParent action in my controller I create Parent (with Id passed in as I need to keep track of that Id [after all I need to know for which ParentId I need to add a child]) looks like this:
[HttpGet]
public ActionResult CreateChild(int id)
{
var newParent = new Parent {
Id = id, Children = new List<Child> { new Child { Name = "ChildName" } } };
return View("~/Views/Home/CreateParent.cshtml", newParent);
}
Page is loaded and user fills in the details and presses "OK". Then this action is run:
[HttpPost]
public ActionResult CreateChild(Parent parent)
{
return View("~/Views/Home/ViewChildren.cshtml", AddChild(parent));
}
AddChild(parent) is a private function, which deals with persisting children for a given parent and it returns a parent model with updated children.
Here is my problem/question: data is lost between calls. When I create a parent in [HttpGet] everything is fine, I can see the values properly set in a debugger but when I fill in Child data and press "OK" in [HttpPost] Parent comes in with all values, including my newly populated Child as null (actually only Id is field seems to be carried over, which I also don't understand). Why?
I may add that if I do this with a view that's typed to a Child then this works. I can't really just pass a Child because I also need to track/carry-over Parent's Id. I don't understand this either.
Here are the views (first is to view children under a parent) and this one is working fine:
@model Parent
@{
ViewBag.Title = "AddChild";
}
<h2>Children for parent @Model.Name </h2>
<p>
@Html.ActionLink("Create New", "CreateChild", new {id = @Model.Id})
</p>
<table>
<tr>
<th>
Name
</th>
<tr>
@foreach (var child in @Model.Children) {
<tr>
<td>
@Html.DisplayFor(modelItem => child.Name)
</td>
<td>
@Html.ActionLink("Delete", "Delete", new { id=child.Id })
</td>
</tr>
}
</table>
Here is view for creating a child under a parent:
@model Parent
@{
ViewBag.Title = "CreateChild";
}
<h2>Create new child for @Model.Name</h2>
@using (Html.BeginForm())
{
<table>
<tr>
<td>
Name:
</td>
</tr>
@foreach (var child in @Model.Children)
{
<tr>
<td>
@Html.EditorFor(modelItem => child.Name)
</td>
</tr>
}
</table>
<input id="submit" name="submit" type="submit" value="Save" />
}
So when I press "Save" Parent comes in only with Id set to the value that's been passed in. Everything else is set to null. Including Name of the Parent as well as Children.
Here is AddChild method:
private Parent AddChild(Parent parent)
{
var updatedParent = GetParent(int parent.Id);
updatedParent.Children.Add(parent.Children[0]); // this obviously fails as Children is NULL
return updatedParent;
}