robasta robasta -4 years ago 164
C# Question

How do I Bind a Collection (IEnumerable) of a custom type?

I have the following Action to display a form with 3 items :

public ActionResult ReferAFriend()
List<ReferAFriendModel> friends = new List<ReferAFriendModel>();
ReferAFriendModel f1 = new ReferAFriendModel();
ReferAFriendModel f2 = new ReferAFriendModel();
ReferAFriendModel f3 = new ReferAFriendModel();

return View(friends);

and then a Post action

public ActionResult ReferAFriend(IEnumerable<ReferAFriendModel> friends)

My View looks like this:

@model IEnumerable<Models.ReferAFriendModel>
@for(int i=0;i<Model.Count();i++)
@Html.Partial("_ReferAFriend", Model.ElementAt(i));

The partial looks like this:

@model Models.ReferAFriendModel
@Html.LabelFor(i => i.FullName) @Html.TextBoxFor(i => i.FullName)<br />
@Html.LabelFor(i => i.EmailAddress) @Html.TextBoxFor(i => i.EmailAddress)

When I post, I can see the fields are posted in the Request.Form object e.g Request.Form["FullName"] will show: "David Beckham","Thierry Henry". "Chicharito Fergurson" which are the values I entered in the form. But, the in the Post action,the value for 'friends' is always null. The ReferAFriendModel has three public properties Id, EmailAddress and FullName.

What am I doing wrong?

Answer Source

You may take a look at the following blog post about the wire format for arrays and dictionaries. Personally I always use editor templates in my views which take care of generating proper names of the input fields so that the default model binder is able to bind the values correctly.

@model IEnumerable<ReferAFriendModel>
@using (Html.BEginForm())
    <input type="submit" value="OK" />

and in the corresponding editor template (~/Views/Shared/EditorTemplates/ReferAFriendModel.cshtml):

@model ReferAFriendModel
@Html.EditorFor(x => x.Prop1)
@Html.EditorFor(x => x.Prop2)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download