I have a problem when trying to retrieve values from a list within a complex model. I have downloaded and set up the Contoso University sample from http://code.msdn.microsoft.com/ASPNET-MVC-Application-b01a9fe8, where I am able to reproduce the same issue that I have in my own project, and was wondering if anyone could assist.
I have made 2 changes to the Contoso sample:
1) In StudentController.cs, I have amended the list of values supplied to the Bind of the Edit HttpPost action (Enrollments is now listed in the Include list):
[HttpPost]
[ValidateAntiForgeryToken]
publicActionResult Edit([Bind(Include = "ID, LastName, FirstMidName, EnrollmentDate,Enrollments")]Student student)
{
// [Bind(Include = "ID, LastName, FirstMidName, EnrollmentDate, Enrollments")]
try
{
if (ModelState.IsValid)
{
db.Entry(student).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (RetryLimitExceededException/* dex */)
{
//Log the error (uncomment dex variable name and add a line here to write a log.
ModelState.AddModelError("","Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
return View(student);
}
2) I have added code to output the list of Enrollments immediately before the Save button form-group, so that the Student\Edit.cshtml file is now as follows:
@modelContosoUniversity.Models.Student
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<divclass="form-horizontal">
<h4>Student</h4>
<hr/>
@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.ID)
<divclass="form-group">
@Html.LabelFor(model => model.LastName,new { @class ="control-label col-md-2" })
<divclass="col-md-10">
@Html.EditorFor(model => model.LastName)
@Html.ValidationMessageFor(model => model.LastName)
</div>
</div>
<divclass="form-group">
@Html.LabelFor(model => model.FirstMidName,new { @class ="control-label col-md-2" })
<divclass="col-md-10">
@Html.EditorFor(model => model.FirstMidName)
@Html.ValidationMessageFor(model => model.FirstMidName)
</div>
</div>
<divclass="form-group">
@Html.LabelFor(model => model.EnrollmentDate,new { @class ="control-label col-md-2" })
<divclass="col-md-10">
@Html.EditorFor(model => model.EnrollmentDate)
@Html.ValidationMessageFor(model => model.EnrollmentDate)
</div>
</div>
<tableclass="table">
<tr>
<th>Course Title</th>
<th>Grade</th>
</tr>
@foreach (var itemin Model.Enrollments)
{
<tr>
<td>
@Html.EditorFor(modelItem => item.Course.Title)
</td>
<td>
@Html.EditorFor(modelItem => item.Grade)
</td>
</tr>
}
</table>
<divclass="form-group">
<divclass="col-md-offset-2 col-md-10">
<inputtype="submit"value="Save"class="btn btn-default"/>
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List","Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
Now add a breakpoint at the if (ModelState.IsValid)line that in step 1), and browse to http://localhost:xxxx/Student/Edit/3. You should see a list of enrollments for the student, which are editable.
Now click the Save button, and observe the value of the student parameter once the breakpoint has been reached. You’ll see that the Enrollments within the student object is set to null.
What changes do I need to make to enable these values to be accessible from within the Mvc action?
Ben Grice