I am developing a simple website where there are students and there are courses. What is interesting is I can't seem to add a course to my student and make it save. I call the savechanges() method but on my cshtml page, my viewbag does not contain the updated student. Here is what I mean.
Here you can see my ViewBag.Student contains a valid student that has been modified to include two courses under PendingCourses. However, when I load my cshtml page, my ViewBag.Student contains:
So there is definitely some disconnect although I can't figure out what it is. So basically my Details page sets the ViewBag by doing a where statement on the context. This context is modified and saved with the AddCourseToStudent function and then the ViewBag.Student is read in the cshtml. Any help is much appreciated. Below are my files for reference.
Details Function:
// GET: Student/Details/5
[Authorize]
public ActionResult Details(int id)
{
using (var context = new StudentDbContext())
{
ViewBag.Student = context.Students.Where(u => u.id == id).FirstOrDefault();
}
var context2 = new ApplicationDbContext();
var userList = context2.Users.OrderBy(r => r.UserName).ToList().Select(rr => new SelectListItem { Value = rr.UserName.ToString(), Text = rr.UserName }).ToList();
ViewBag.Users = userList;
return View();
}
CSHTML:
@{
ViewBag.Title = "Details";
Layout = "~/Views/Shared/_Layout.cshtml";
SchoolRegistration.Models.Student student = ViewBag.Student;
List<SchoolRegistration.Models.Course> completedCourses = student.CompletedCourses;
List<SchoolRegistration.Models.Course> pendingCourses = student.PendingCourses;
List<SchoolRegistration.Models.Course> failedCourses = student.FailedCourses;
List<int> yearRange = new List<int>();
if (completedCourses != null) {
foreach (SchoolRegistration.Models.Course course in completedCourses)
{
if (!yearRange.Contains(course.Year))
{
yearRange.Add(course.Year);
}
}
}
if (pendingCourses != null)
{
foreach (SchoolRegistration.Models.Course course in pendingCourses)
{
if (!yearRange.Contains(course.Year))
{
yearRange.Add(course.Year);
}
}
}
if (failedCourses != null)
{
foreach (SchoolRegistration.Models.Course course in failedCourses)
{
if (!yearRange.Contains(course.Year))
{
yearRange.Add(course.Year);
}
}
}
yearRange.Sort();
}
<h2>Details</h2>
@if (TempData["Success"] != null)
{
if (TempData["Success"] == "nocourse")
{
<div style="background-color:aliceblue">
<p><strong>Success:</strong><a href="#" id="createCourseLink">Create Course?</a></p>
</div>
}
else
{
<div style="background-color:aliceblue">
<p><strong>Success:</strong> @TempData["Success"].ToString()</p>
</div>
}
}
<h3>@student.FirstName @student.LastName - @student.StudentID</h3>
<h4>@student.GradeLevel - @student.ExpectedGraduation</h4>
<h3>Degree Audit</h3>
@using (Html.BeginForm("GetCourse", "Student", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<hr />
@Html.ValidationSummary("", new { @class = "text-danger" })
<p>Start Year: @Html.DropDownList("startYear", (IEnumerable<SelectListItem>)yearRange.ToList().Select(rr => new SelectListItem { Value = rr.ToString(), Text = rr.ToString() }).ToList(), "Select...") Start Semester: @Html.DropDownList("startSemester", EnumHelper.GetSelectList(typeof(SchoolRegistration.Models.Semesters)), "Select...")</p>
<p>End Year: @Html.DropDownList("endYear", (IEnumerable<SelectListItem>)yearRange.ToList().Select(rr => new SelectListItem { Value = rr.ToString(), Text = rr.ToString() }).ToList(), "Select...") End Semester: @Html.DropDownList("endSemester", EnumHelper.GetSelectList(typeof(SchoolRegistration.Models.Semesters)), "Select...")</p>
<input type="submit" value="Search" id="btnStudentFilter" />
}
<h3>Course Management</h3>
@using (Html.BeginForm("GetCourseForStudent", "Student", FormMethod.Post))
{
@Html.AntiForgeryToken();
<hr />
<p><strong>Subject: </strong>@Html.DropDownList("cat", EnumHelper.GetSelectList(typeof(SchoolRegistration.Models.Categories)), "Select...")</p>
<p><strong>CAT NO: </strong>@Html.TextBox("CourseId")</p>
<p><strong>Section: </strong>@Html.TextBox("SectionId")</p>
<p><strong>Year: </strong>@Html.TextBox("Year")</p>
<p><strong>Semester: </strong>@Html.DropDownList("semester", EnumHelper.GetSelectList(typeof(SchoolRegistration.Models.Semesters)), "Select...")</p>
<input type="submit" value="Search" />
}
@if (TempData["RetrievedCourses"] != null)
{
List<SchoolRegistration.Models.Course> courses = (List<SchoolRegistration.Models.Course>)TempData["RetrievedCourses"];
for (int i = 0; i < courses.Count; i++)
{
<p>@courses[i].Name - @courses[i].Category @courses[i].CourseId . @courses[i].SectionId - @courses[i].Credits Credits | @Html.ActionLink("Add to Student", "AddCourseForStudent", "Student", new { courseId = courses[i].id, studentId = student.id},null)</p>
}
<p>Course Search DIV Link</p>
}
AddCourseToStudent:
public ActionResult AddCourseForStudent(int courseId, int studentId)
{
using (var context = new StudentDbContext())
{
Student student = context.Students.Where(u => u.id == studentId).FirstOrDefault();
Course course = context.Courses.Where(u => u.id == courseId).FirstOrDefault();
List<Course> completed = student.CompletedCourses;
List<Course> pending = student.PendingCourses;
List<Course> failed = student.FailedCourses;
if (completed == null)
completed = new List<Course>();
student.CompletedCourses = completed;
if (pending == null)
pending = new List<Course>();
student.PendingCourses = pending;
if (failed == null)
failed = new List<Course>();
student.FailedCourses = failed;
pending.Add(course);
try
{
context.Entry(student).State = System.Data.Entity.EntityState.Modified;
context.SaveChanges();
ViewBag.Student = student;
}
catch (DbEntityValidationException e)
{
foreach (var eve in e.EntityValidationErrors)
{
Debug.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
foreach (var ve in eve.ValidationErrors)
{
Debug.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
ve.PropertyName, ve.ErrorMessage);
}
}
throw;
}
}
TempData["Success"] = "Courses added to student.";
return Redirect(Request.UrlReferrer.ToString());
}
Models:
public class InstructorViewModels
{
}
public enum GradeLevels
{
Freshman,
Sophmore,
Junior,
Senior,
Graduate
}
public enum Categories
{
CSCI
}
public enum Semesters
{
FA,
SP,
S1,
S2,
S3,
IN
}
public enum CourseTypes
{
Humanities
}
public class Student
{
public int id { get; set; }
[Required]
public int StudentID { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public string MiddleName { get; set; }
[Required]
public GradeLevels GradeLevel { get; set; }
[Required]
public List<Course> CompletedCourses { get; set; }
[Required]
public List<Course> PendingCourses { get; set; }
[Required]
public List<Course> FailedCourses { get; set; }
[Required]
public int ExpectedGraduation { get; set; }
}
public class Course
{
public int id { get; set; }
public int CourseId { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int SectionId { get; set; }
[Required]
public Categories Category { get; set; }
[Required]
public int Credits { get; set; }
[Required]
public Semesters Semester { get; set; }
[Required]
public int Year { get; set; }
[Required]
public string InstructorId { get; set; }
public CourseTypes CourseType { get; set; }
}
Database: