我有一个新手问题,我过去几天试图了解这个问题。希望有人能够帮助我理解编程流程。
假设我有一个模型,信息存储在数据库中:
public class Student
{
public int studentID { get; set; }
public string studentName { get; set; }
public strin studentGrade {get; set; }
}
public class StudentDBContext : DbContext
{
public DbSet<Student> Students { get; set; }
}
我希望将其显示在视图中,并附加复选框,以便我可以选择要升级到下一年级的学生。我读到一种方法是通过放入视图模型:
public class StudentViewModel
{
public bool promoted { get; set; }
public Student stu { get; set; }
}
但我坚持这是这样做的方法吗?如果是的话,你如何进入视图,它将显示所有学生旁边的复选框。之后,我想更新勾选复选框的学生的所有成绩。例如:
学生A,学生B,学生D从1年级升入2年级。所以我想展示学生,勾选学生A,B和D并提交更新成绩。
将非常感谢分步示例。
更新1:
控制器:
[HttpGet]
public ViewResult CheckBox()
{
var studentViewModels = db.Students.Select(m => new StudentViewModel()
{
stu = m
}).ToList();
return View(studentViewModels);
}
[HttpPost]
public ActionResult CheckBox(IList<studentViewModel> list)
{
foreach (var stuUpdate in list.Where(m => m.promoted))
{
var stuRow = db.Students.Find(stuUpdate.stu.studentID);
stuRow.studentName = stuRow.studentName + "1";
db.Entry(stuRow).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("CheckBox");
}
return RedirectToAction("CheckBox");
}
查看:
@model IList<School.ViewModels.StudentViewModel>
@using (Html.BeginForm())
{
<table>
<tr>
<th>
</th>
<th>
student ID
</th>
<th>
student name
</th>
<th>
student grade
</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.CheckBoxFor(modelItem => item.promoted)
@Html.HiddenFor(modelItem => item.stu.studentID)
</td>
<td>
@Html.DisplayFor(modelItem => item.stu.studentID)
</td>
<td>
@Html.DisplayFor(modelItem => item.stu.studentName)
</td>
<td>
@Html.DisplayFor(modelItem => item.stu.studentGrade)
</td>
</tr>
}
</table>
<input type="submit" value="save" />
}
但是目前遇到以下错误: 值不能为空。 参数名称:source
Source Error:
foreach (var stuUpdate in list.Where(m => m.promoted))
答案 0 :(得分:2)
一个非常基本的“一步一步”(在SO中完成,所以我可能犯了一些错误,但你已经有了这个想法)。
你总是有几种方法来做这些事情,所以......真的把它作为一个样本,并找到其他例子来获得其他想法。
好吧,首先,在您的控制器中,您将进行GET操作(查看列表)。
[HttpGet]
public ViewResult StudentList() {
//retrieve all students. With the Select, we create a new instance of StudentViewModel for each student.
//assuming StudentDbContext being a property of your controller, if it's not, you can instantiate a new one (in a using clause)
var studentViewModels = StudentDbContext.Students
.Select(m => new StudentViewModel() {
stu = m
//we don't say nothing about promoted :
//it will be there as "false" by default, which is probably what we want.
}).ToList();
//now we've got a list of StudentViewModel. This will be the model of our view
return View(studentViewModels);
}
然后我们有了一个视图,StudentList.cshtml
在这个视图中,我们将显示一个表格,每个学生都有一行:studentId(在这种情况下隐藏),名称(仅显示),等级(仅显示)和复选框。
我们需要一个for循环(不是foreach)来获得精细的模型绑定。
@model IList<StudentViewModel>
@using (Html.BeginForm()) {
<table>
<tr>
<th>Student name</th>
<th>Student grade</th>
<th>Promote</th>
</tr>
@for (var i = 0; i < Model.Count(); i++) {
<tr>
<td>@Html.HiddenFor(m => Model[i].Student.studentID)
@Html.DisplayFor(m => Model[i].Student.studentName)
</td>
<td>@Html.DisplayFor(m => Model[i]Student.studentGrade)</td>
<td>@Html.CheckBoxFor(m => Model[i].promoted)</td>
</tr>
}
</table>
<input type="submit" value="save" />
}
此表单将导致另一个POST操作(与GET相同的名称,具体取决于您在Html.BeginForm
中的内容)
[HttpPost]
public ActionResult StudentList(IList<StudentViewModel> list) {
//we treat only the lines where checkbox has been checked
foreach (var studentViewModel in list.Where(m => m.promoted) {
var student = StudentDBContext.GetById(studentViewModel.Student.studentID);//get student entity instance from context
student.studentGrade ="<new value>";
StudentDBContext.SaveChanges();//save changes, you must have such a method somewhere.
}
return Action("StudentList");
}
小细节:
尝试尊重一些非常基本的“通常”做法:例如在c#中,属性应以大写字母开头(因此StudentGrade,StudentName,Promoted等)。