I have two related POCOs
public class Parent
{
public Guid Id {get; set;}
public IList<Child> ChildProperty {get; set;}
}
public class Child
{
public Guid Id {get; set;}
public String Name {get; set;}
}
and I have a .cshtml Razor view with
<div>
@{
var children =
new SelectList(Child.FindAll(), "Id", "Name").ToList();
}
@Html.LabelFor(m => m.Child)
@Html.DropDownListFor(m => m.Child.Id, , children, "None/Unknown")
</div>
I’d like to do the following in my controller class:
[HttpPost]
public ActionResult Create(Parent parent)
{
if (TryUpdateModel(parent))
{
asset.Save();
return RedirectToAction("Index", "Parent");
}
return View(parent);
}
Such that if the user selects “None/Unknown”, the child value of the parent object in the controller is null but if the user selects any other value (i.e. an ID of a child object retrieved from the database), the child value of the parent object is instantiated and populated with that ID.
Basically I’m struggling with how to persist a list of possible entities across the HTTP stateless boundary such that one of the entities is properly rehydrated and assigned via the default model binder. Am I just asking for too much?
Yes, you are asking for too much.
All that’s sent with the POST request is the ID of the selected entity. Don’t expect to get much more than that. If you want to rehydrate or whatever you should query your database. The same way you did in your GET action to populate the child collection.
Oh and there’s a problem with your POST action => you are calling the default model binder twice.
Here are the 2 possible patterns (personally I prefer the first but the second might be useful in some situations as well when you want to manually call the default model binder):
or:
In your code you’ve made some mix of the two which is wrong. You are basically invoking the default model binder twice.