gpt4 book ai didi

c# - 使用 ASP.NET Core MVC MultiSelectList 更新多对多实体

转载 作者:行者123 更新时间:2023-11-30 17:36:35 25 4
gpt4 key购买 nike

我有一个表单,我想更新一个与另一个实体具有多对多关系的实体,我正在尝试使用 select 标签来创建 MultiSelectList 控制。我将 ASP.NET Core 1.0 与 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; }
}

View 模型:

public class StudentVM
{
public Student Student { get; set; }
public IEnumerable<SelectListItem> CourseList { get; set; }
}

View :

@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>

Controller 的 Action 方法:

[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);
}

现在问题来了......

问题一

StudentVM 进入EditHttpPost 变体时,这两个属性都是null。为什么在进入 Edit 函数之前清除 View 模型中的属性?我已确认它们在 HttpGet 变体中设置正确,并且数据在 View 中正确显示。

问题2

由于进入Edit 的数据无效,我无法测试我的数据库更新。我从 SelectList 中获取所选项目以及从 Student.Courses 中添加/删除项目的方法是否正确?我找不到很多关于 EF Core 中多对多关系的文档。

我对 ASP.NET 和 Entity Framework 比较陌生,所以任何提示或批评都将不胜感激。

最佳答案

您不能绑定(bind) <select>到复杂对象的集合(这就是 MultiSelectList 是什么。一个 <select multiple> 元素回发一个包含其选定选项值的数组(在您的例子中,这将是一个包含类(class) Id 值的数组)。您的模型需要要绑定(bind)的属性。假设他 IdCourse 属性是 int ,则添加以下属性

public IEnumerable<int> SelectedCourses { get; set; }

另请注意,设置 selectedValues MultiSelectList中的属性(property)构造函数被标签助手忽略(在内部,该方法根据属性的值构建一个新的 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);

然后在 View 中,使用

<select asp-for="SelectedCourses" asp-items="Model.CourseList"></select>

而在POST方法中,SelectedCourses的值将包含一系列类(class) Id您在 View 中选择的值。

关于c# - 使用 ASP.NET Core MVC MultiSelectList 更新多对多实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39177022/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com