I have a View Model that consists of an Applicant
object and a TeamMember
collection. When I post the model back the Team collection is always null. I've tried changing the collection from my original IEnumarable
to a List
but that didn't make a difference. So I changed the Controllers Edit Action to accept the FormCollection
, and verified there was data in viewModel["member.FirstName"]
. I'm lost as to why the binding isn't working. I tried to clean out my code samples as much as possible but I'm confused at what I'm missing. Any help is greatly appreciated!
View Model Properties
public class MyViewModel
{
public Applicant ApplicantInfo { get; set; }
public List<TeamMember> TeamMembers { get; set; }
}
Controller
[HttpPost]
public ActionResult Edit(MyViewModel viewModel)
{
// viewModel.ApplicantInfo has the form data
// viewModel.TeamMembers = null
}
View
<% using (Html.BeginForm())
{%>
<h3>
<a href="#">Applicant Information</a>
</h3>
<label>
City
<%: Html.TextBoxFor(m => Model.ApplicantInfo.City)%>
</label>
<label>
State
<%: Html.TextBoxFor(m => Model.ApplicantInfo.State)%>
</label>
<h3>
<a href="#">Team</a>
</h3>
<div>
<% foreach (var member in Model.TeamMembers)
{ %>
<div class="editor-field">
<%: Html.DropDownList("member.Type", Model.GetMemberTypes(member.MemberType.TypeId))%>
</div>
<div class="editor-field">
<%: Html.EditorFor(m => member.FirstName)%>
</div>
<div class="editor-field">
<%: Html.EditorFor(m => member.LastName)%>
</div>
<div class="editor-field">
<%: Html.EditorFor(m => member.Title)%>
</div>
<%} %>
</div>
<p>
<input type="submit" value="Save" />
</p>
<% } %>
I believe that input tags associated with items in a collection (when the model itself is not a collection) need to have an index in the name attribute before you can bind posted data to a view model. Here is the way I usually accomplish this...
I've also used the template as suggested by Shea, but I have a tad more code trying to force it to render brackets/indexes.
Here is an old but still relevant article from Phil Haack on the topic.
Try using this:
Then, make a shared editor template with a model type of
TeamMember
. MVC should handle binding everything back to your viewmodel on post for you.