4

This question might be a reiteration of a previous question, if it is please post the link. Either way I'll still go through with this post.

I have this model:

public class Employee {
    //omitted for brevity

    public virtual ICollection<ProfessionalExperience> ProfessionalExperiences { get; set; }
    public virtual ICollection<EducationalHistory> EducationalHistories { get; set; }
}

public class ProfessionalExperience {
    // omitted for brevity
}

public class EducationalHistory {
    // omitted for brevity
}

I'm displaying on my View with this Action:

[HttpGet]
public ActionResult Edit(int id) {
    using(var context = new EPMSContext()) {
        var employees = context.Employees.Include("ProfessionalExperiences").Include("EducationalHistories");

        var employee = (from item in employees
                        where item.EmployeeId == id && item.IsDeleted == false
                        select item).FirstOrDefault();

        return View(employee);
    }
}

Here is my View:

@using(Html.BeginForm()) {
  <div class="editor-label">First Name:</div>
  <div class="editor-field">@Html.TextBoxFor(x => x.FirstName)</div>
  <div class="editor-label">Middle Name:</div>
  <div class="editor-field">@Html.TextBoxFor(x => x.MiddleName)</div>

  @foreach(var item in Model.ProfessionalExperiences) {
      Html.RenderPartial("ProfExpPartial", item);
  }

  @foreach(var item in Model.EducationalHistories) {
      Html.RenderPartial("EducHistPartial", item);
  }
  <input type="submit" value="Save" />
}

I display the child collection on the view using a foreach and using a partial view for each collection.

When calling my Post Edit Action the employee model has the child collections set to null.

[HttpPost]
public ActionResult Edit(Employee employee) {
    using(var context = new EPMSContext()) {

    }

    return View();
}

What am I missing to get the child collections to correctly?

Thank you!

tereško
  • 58,060
  • 25
  • 98
  • 150
Erick Garcia
  • 832
  • 2
  • 12
  • 29
  • Can you show what code you are using to initiate the POST request? Also showing an example HTTP POST request would help as well, i.e. what data are you POSTing? It sounds like ASP.NET is failing to deserialize the collection, so it would help see what data you are trying to send. – Eric LaForce Sep 08 '12 at 02:15
  • I've updated my question I hope I got your suggestion right. – Erick Garcia Sep 08 '12 at 05:46
  • Also, I've checked the Request.Form object and I saw that the collections are in the request. How would I enable my child collections to be included in the Employee object I'm passing? – Erick Garcia Sep 08 '12 at 06:39

1 Answers1

2

I think the problem is related to the way MVC expects collection elements to be built (their names in the html). Take a look at this SO answer: https://stackoverflow.com/a/6212877/1373170, especially the link to Scott Hanselman's post.

Your problem lies in the fact that if you manually iterate and do individual RenderPartial() calls, the input fields will not have indexes, and the DefaultModelBinder will not know how to construct your collection.

I would personally create Editor Templates for your two ViewModel types, and use @Html.EditorFor(model => model.EducationalHistories) and @Html.EditorFor(model => model.ProfessionalExperiences).

Community
  • 1
  • 1
Pablo Romeo
  • 11,298
  • 2
  • 30
  • 58
  • Okay, I've made my editor templates. I've used a foreach to iterate over the list of child collections. Did I do it right? – Erick Garcia Sep 08 '12 at 07:49
  • You shouldn't need the foreach at all. Let MVC handle the iteration and solving the right template for it. – Pablo Romeo Sep 08 '12 at 15:09
  • I did try just using the class being contained int he IEnumerable for the editor template (even in the display template I mean) but there is an error saying that the I'm trying to pass a collection to the view that only handles just the class. I forgot to mention that my child collections are set to virtual. Should I remove that to disable lazy loading for just those members of the parent entity? – Erick Garcia Sep 09 '12 at 01:41
  • Strange. How are you calling the EditorFor or DisplayFor? – Pablo Romeo Sep 10 '12 at 13:20
  • It works now. I used [this](http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/) helper and I even cleaned-up my model's navigation properties just to be sure and so that I don't have to turn lazy loading off... – Erick Garcia Sep 14 '12 at 02:38