I am working on a project to help students and advisers select the best courses for the next semester, using ASP.NET MVC 5. The first step is for the student to select the courses he has already taken from a list. The controller which displays the list is:
public ActionResult AddCourseVM (int? id)
{
Student student = db.Students.Find(id);
// List<BaseCourse> potentialCourses = student.StudentConcentration.RequiredCourses.ToList();
List<BaseCourse> potentialCourses = db.BaseCourses.ToList();
AddCourseViewModel vModel = new AddCourseViewModel(student, potentialCourses);
List<Course> listCourses = new List<Course>();
foreach(BaseCourse baseC in potentialCourses)
{
Course c = new Course();
c.BaseCourse = baseC;
c.Student = student;
listCourses.Add(c);
}
vModel.PossibleCourses = listCourses;
return View("AddCourseVM", vModel);
}
The ViewModel is:
public class AddCourseViewModel
{
public Student Student { get; set; }
public List<BaseCourse> AvailCourses { get; set; }
public List<Course> PossibleCourses { get; set; }
public AddCourseViewModel(Student s, List<BaseCourse> c)
{
Student = s;
AvailCourses = c;
PossibleCourses = new List<Course>();
}
public AddCourseViewModel()
{
Student = new Student();
AvailCourses = new List<BaseCourse>();
PossibleCourses = new List<Course>();
}
}
The Course objects are specific instances of a course (for a given student, in a certain semester, etc), the BaseCourse objects are the individual courses from the course catalog.
I am displaying the possible courses in a list using this view:
@model CMPSAdvising.ViewModels.AddCourseViewModel
@{
ViewBag.Title = "AddCourseVM";
}
<h2>Add Courses</h2>
<div>
<p>Name: @Model.Student.FirstName @Model.Student.LastName</p>
<p>W#: @Model.Student.WNumber</p>
</div>
<div>
<p>Select the Courses You Have Taken</p>
</div>
<div>
@using (Html.BeginForm("AddCourseVM","Students"))
{
@Html.AntiForgeryToken();
<div>
<table class="table table-bordered">
<tr>
<th>Course</th>
<th>Department</th>
<th>Number</th>
<th>Check if Taken</th>
<th>Semester</th>
<th>Grade</th>
</tr>
@foreach (var course in Model.PossibleCourses)
{
<tr>
<td>@course.BaseCourse.Name</td>
<td>@course.BaseCourse.CourseNumber</td>
<td>@course.BaseCourse.CourseNumber</td>
<td>@Html.CheckBoxFor(s => course.Selected)</td>
<td>@Html.TextBoxFor(m => course.Semester)</td>
<td>@Html.TextBoxFor(g => course.Grade)</td>
</tr>
}
</table>
<input type="submit" value="Save Classes Taken" class="btn btn-default" />
</div>
}
</div>
And finally the controller that receives the POST when the user hits the button:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddCourseVM (AddCourseViewModel vModel)
{
Student stu = vModel.Student;
foreach (Course c in vModel.PossibleCourses)
{
if (c.Selected)
{
stu.CoursesTaken.Add(c);
}
}
db.Entry(stu).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("ListTakenCourses", new { id = stu.ID });
}
My problem is that the AddCourseViewModel object (vModel) is coming back null. I would like to get the ViewModel back from the web page as an object, or at least get the list of courses that were checked and the student's ID.