使用ASP更新多对多实体.. NET Core MVC MultiSelectList
本文关键字:Core MVC MultiSelectList NET ASP 更新 使用 实体 | 更新日期: 2023-09-27 18:04:09
我有一个表单,我想更新一个实体与另一个实体的多对多关系,我试图使用select
标签来创建MultiSelectList
控件。我用的是ASP。. NET Core 1.0 with Entity Framework.
假设我有以下实体:
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public List<StudentCourse> Courses { get; set; }
}
public class Course
{
public int Id { get; set; }
public string Name { get; set; }
public List<StudentCourse> Students { get; set; }
}
public class StudentCourse
{
public int StudentId { get; set; }
public Student Student { get; set; }
public int CourseId { get; set; }
public Course Course { get; set; }
}
视图模型:
public class StudentVM
{
public Student Student { get; set; }
public IEnumerable<SelectListItem> CourseList { get; set; }
}
视图:@model StudentVM
<form asp-action="Edit">
<div class="form-horizontal>
<div class="form-group">
<select asp-for="CourseList" asp-items="Model.CourseList" />
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
</form>
控制器的动作方法:
[HttpGet]
public async Task<IActionResult> Edit(Student student)
{
var viewmodel = new StudentVM {
Student = student,
CourseList = new MultiSelectList(
_db.Courses,
"Id",
"Name",
student.Courses
.Select(sc => sc.CourseId));
};
return View(viewmodel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(StudentVM viewmodel)
{
if (viewmodel.Student == null)
return NotFound();
if (ModelState.IsValid)
{
Student student = viewmodel.Student;
var newCourses = viewmodel.CourseList
.Where(i => i.Selected)
.Select(c => new StudentCourse {
StudentId = student.Id,
CourseId = Convert.ToInt32(c.Value)
});
student.Courses.RemoveAll(sc => !newCourses.Contains(sc));
student.Courses.AddRange(
newCourses.Where(nc => !student.Courses.Contains(nc)));
_db.Update(student);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(viewmodel);
}
现在是问题…
问题1
当StudentVM
进入Edit
的HttpPost
变体时,两者的性质都是null
。为什么视图模型中的属性在进入Edit
函数之前被清除?我已经确认它们在HttpGet
变体中被正确设置,并且数据在视图中正确显示。
问题2
由于进入Edit
的数据无效,我无法测试我的数据库更新。我从SelectList
中获得选定项目并从Student.Courses
中添加/删除项目的方法是否正确?我没能找到很多关于EF Core中多对多关系的文档。
我对ASP相当陌生。. NET和实体框架,所以任何提示或批评将非常感谢。
您不能将<select>
绑定到复杂对象的集合(这就是MultiSelectList
)。<select multiple>
元素返回它所选选项值的数组(在您的示例中是课程Id
值的数组)。您的模型需要绑定到一个属性。假设Course
的Id
属性为int
,则添加以下属性
public IEnumerable<int> SelectedCourses { get; set; }
还要注意,在MultiSelectList
构造函数中设置selectedValues
属性会被标记帮助器忽略(该方法内部会根据该属性的值构建一个新的IEnumerable<SelectListItem>
)。GET方法中的代码应该是
var viewmodel = new StudentVM
{
Student = student,
CourseList = new SelectList(_db.Courses, "Id", "Name"),
SelectedCourses = student.Courses.Select(sc => sc.CourseId)
};
return View(viewmodel);
然后在视图中使用
<select asp-for="SelectedCourses" asp-items="Model.CourseList"></select>
在POST方法中,SelectedCourses
的值将包含您在视图中选择的Course Id
值的数组