您发现这很困难,因为您没有充分利用MVC框架的功能,所以请允许我提供一个工作示例。
首先亮相,让我们创建一个视图模型来封装视图的数据要求:
public class SubjectGradesViewModel
{
public SubjectGradesViewModel()
{
Subjects = new List<Subject>();
}
public List<Subject> Subjects { get; set; }
}
接下来,创建一个类来表示你的主题模式:
public class Subject
{
public int Id { get; set; }
public string Name { get; set; }
public List<Student> StudentEntries { get; set; }
}
最后一个类来表示一个学生:
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Grade { get; set; }
}
在这一点上,你有所有你需要的类代表你的数据。现在,让我们创建两个控制器动作,包括一些样本数据,所以你可以看到这是如何工作:
public ActionResult Index()
{
var model = new SubjectGradesViewModel();
// This sample data would normally be fetched
// from your database
var compsci = new Subject
{
Id = 1,
Name = "Computer Science",
StudentEntries = new List<Student>()
{
new Student { Id = 1, Name = "CompSci 1" },
new Student { Id = 2, Name = "CompSci 2" },
}
};
var maths = new Subject
{
Id = 2,
Name = "Mathematics",
StudentEntries = new List<Student>()
{
new Student { Id = 3, Name = "Maths 1" },
new Student { Id = 4, Name = "Maths 2" },
}
};
model.Subjects.Add(compsci);
model.Subjects.Add(maths);
return View(model);
}
[HttpPost]
public ActionResult Index(SubjectGradesViewModel model)
{
if (ModelState.IsValid)
{
return RedirectToAction("Success");
}
// There were validation errors
// so redisplay the form
return View(model);
}
现在是时候建造的意见,当涉及到数据发送回控制器,这部分就显得尤为重要。首先登场的是Index
观点:
@model SubjectGradesViewModel
@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
@Html.EditorFor(m => m.Subjects) <br />
<input type="submit" />
}
你我只是使用Html.EditorFor
,同时传递Subjects
作为参数注意。我这样做的原因是因为我们要创建一个EditorTemplate
来代表Subject
。稍后我会解释更多。现在,只知道EditorTemplates
和DisplayTemplates
是MVC中的特殊文件夹名称,因此它们的名称和位置很重要。
我们实际上要创建两个模板:一个用于Subject
,另一个用于Student
。要做到这一点,请按照下列步骤操作:
- 创建视图的当前文件夹内的文件夹
EditorTemplates
(例如,如果你的观点是Home\Index.cshtml
,创建文件夹Home\EditorTemplates
)。
- 在该目录中创建一个名称与您的模型匹配的强类型视图(即在这种情况下,您将创建两个视图,分别称为
Subject.cshtml
和Student.cshtml
(同样,命名很重要))。
Subject.cshtml
应该是这样的:
@model Subject
<b>@Model.Name</b><br />
@Html.HiddenFor(m => m.Id)
@Html.HiddenFor(m => m.Name)
@Html.EditorFor(m => m.StudentEntries)
Student.cshtml
应该是这样的:
@model Student
@Html.HiddenFor(m => m.Id)
@Html.HiddenFor(m => m.Name)
@Html.DisplayFor(m => m.Name): @Html.EditorFor(m => m.Grade)
<br />
就是这样。如果您现在构建并运行此应用程序,请在POST
索引操作中添加一个断点,您会看到模型已正确填充。
那么,什么是EditorTemplates
,和他们的对应,DisplayTemplates
?它们允许您创建视图的可重用部分,使您可以更多地组织您的视图。
关于他们的好处是模板帮手,即Html.EditorFor
和Html.DisplayFor
,足够聪明,知道他们何时处理集合的模板。这意味着您不必循环播放项目,每次都需要手动调用模板。您也不必执行任何null
或Count()
检查,因为帮助人员将为您处理所有问题。你留下的观点是干净的,没有逻辑。
EditorTemplates
当您希望将收集发布到控制器操作时,也会生成适当的名称。这使得模型绑定到一个列表,比自己生成这些名称要简单得多。有时你仍然需要这样做,但这不是其中之一。
你如何将模型发送到'OptionalMarks' GET方法的视图? –
是的。首先找到一个科目列表,并为每个科目,得到一个学生名单 –