我使用 Entity Framework Code First 来生成我的数据库,所以我定义了一个对象,如下所示:
public class Band
{
public int Id { get; set; }
[Required(ErrorMessage = "You must enter a name of this band.")]
public string Name { get; set; }
// ...
public virtual ICollection<Genre> Genres { get; set; }
}
现在我正在为此创建一个 View ,并且默认的脚手架不会将流派添加到我的表单中,从过去的经验来看,这与我的期望差不多。
网上找了Using ASP.NET MVC v2 EditorFor and DisplayFor with IEnumerable<T> Generic types根据 ASP.NET MVC 3 Custom Display Template With UIHint - For Loop Required?,这似乎最接近我想要的,但对于 Razor 和可能的 MVC 3 似乎没有意义.
目前我已经将流派列表添加到 ViewBag 中,然后在我的创建 View 中循环遍历该列表:
@{
List<Genre> genreList = ViewBag.Genres as List<Genre>;
}
// ...
<ul>
@for (int i = 0; i < genreList.Count; i++)
{
<li><input type="checkbox" name="Genres" id="Genre@(i.ToString())" value="@genreList[i].Name" /> @Html.Label("Genre" + i.ToString(), genreList[i].Name)</li>
}
</ul>
除了尚未处理用户禁用 JavaScript 并且需要重新检查复选框以及使用此信息实际更新数据库的情况之外,它确实会输出我想要的类型。
但这感觉不对,基于 MVC 3 的好坏。
那么在 MVC 3 中处理这个问题的最有效方法是什么?
最佳答案
我不通过 ViewBag 将列表发送到我的 View 中,而是使用我的 View 模型来执行此操作。例如,我做了这样的事情:
我有一个这样的 EditorTemplate:
@model IceCream.ViewModels.Toppings.ToppingsViewModel
<div>
@Html.HiddenFor(x => x.Id)
@Html.TextBoxFor(x =x> x.Name, new { @readonly="readonly"})
@Html.CheckBoxFor(x => x.IsChecked)
</div>
我把它放在我的 Views\IceCream\EditorTemplates 文件夹中。我使用它来显示一些 html 以允许用户“检查”任何特定的浇头。
然后在我看来,我有这样的事情:
@HtmlEditorFor(model => model.Toppings)
这将使用该结果导致我的 EditorTemplate 用于我的 View 模型的 Toppings 属性中的每个浇头。
然后我有一个 View 模型,其中包括 Toppings 集合:
public IEnumerable<ToppingsViewModel> Toppings { get; set; }
在我的 Controller 中,除其他外,我检索浇头(但在我的情况下我这样做)并将我的 View 模型的属性设置为该浇头集合。在编辑的情况下,之前可能已经选择了浇头,我设置了 TopingsViewModel 的 IsChecked 成员,它会将相应的复选框设置为选中。
这样做提供了正确的模型绑定(bind),因此当用户检查一些浇头时,集合中的底层项目会反射(reflect)这些选择。对我来说很好,希望对你有帮助。
关于asp.net-mvc-3 - 将 ASP.NET MVC 3 与 Razor 一起使用,将 ICollection 添加到 Create View 的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7229836/