我想在编辑的列表框中显示教师和所有指定的教师课程(多对多关系:课程,教师和CourseTeacher)。 (我想突出显示已经选择的课程,如果用户更改了选择,它将反映在数据库中)。
我的问题是它适用于Get方法,但是当我发布更新教师和相关课程时,它不会自动执行(更新教师信息,但不会选择课程),尽管它已经分配了所有课程宾语。
我是MVC的新手,所以我甚至不确定我的模型是否正确。但我想问题出在post方法中。(最后一段代码,请参阅我的评论)。
要清楚。我已经有了一系列课程。我只想将他们与几位老师联系起来。
到目前为止我做了什么:ViewModel
public class TeacherEditor
{
public Teacher Teacher { get; set; }
public int[] SelectedCourseIds { get; set; }
public MultiSelectList Courses { get; set; }
}
老师模特:
public class Teacher
{
public int TeacherID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<Course> Courses { get; set; }
public Teacher()
{
Courses = new HashSet<Course>();
}
}
查看:
<div class="editor-field">
@Html.ListBoxFor(model=>model.SelectedCourseIds, Model.Courses)
</div>
控制器GET:
public ActionResult Edit(int id = 0)
{
var teacher = db.Teachers.Include(x=>x.Courses).Where(x=>x.TeacherID==id).SingleOrDefault();
if (teacher==null)
{
return HttpNotFound();
}
var selectedCourses = teacher.Courses.Select(x=>x.CourseID);
var model = new TeacherEditor
{
Teacher = teacher,
Courses = new MultiSelectList(db.Courses, "CourseID", "Name", selectedCourses),
SelectedCourseIds = selectedCourses.ToArray()
};
if (model == null)
{
return HttpNotFound();
}
return View(model);
}
控制器POST:
[HttpPost]
public ActionResult Edit(TeacherEditor teacherEditor)
{
if (ModelState.IsValid)
{
foreach (var id in teacherEditor.SelectedCourseIds)
{
Course course = db.Courses.Where(x=>x.CourseID==id).SingleOrDefault();
teacherEditor.Teacher.Courses.Add(course); //Here I'm adding courses back to Teacher object for save.
}
db.Entry(teacherEditor.Teacher).State = EntityState.Modified; /?This doesn't save records to my relationship table. Why?
db.SaveChanges();
return RedirectToAction("Index");
}
return View(teacherEditor);
}
答案 0 :(得分:3)
您的问题是您无法在POST上绑定到MVC(ICollection)中的接口。 DefaultModelBinder不支持绑定到抽象基类和接口。将ICollection<Course> Courses
更改为List<Course> Courses
等具体实施。
然后你可以在视图中用索引表示法表示课程,ListBoxFor应该处理它。
尝试类似:
public class Teacher
{
public int TeacherID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public IQueryable<Course> Courses { get; set; }
public Teacher()
{
Courses = new IQueryable<Course>();
}
}
public class TeacherEditor
{
public Teacher Teacher { get; set; }
public int[] SelectedCourseIds { get; set; }
public List<Course> CourseList
{
get { return Teacher.Courses.ToList(); }
set { Teacher.Courses = value.ToList(); }
}
}