将 ASP.NET MVC 3 与 Razor 结合使用,将 ICollection 添加到 Create 视图的最有效方法是什么?

发布于 2024-12-01 16:13:46 字数 1381 浏览 3 评论 0原文

我正在使用 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; }
}

现在我正在查看为此创建的视图,默认脚手架不会将流派添加到我的表单中,这在过去是这样的体验与我所期望的差不多。

在网上查看我发现 使用 ASP .NET MVC v2 EditorFor 和 DisplayFor 与 IEnumerable通用类型似乎最接近我想要的,但对于Razor和可能的MVC 3似乎没有意义,根据带有 UIHint 的 ASP.NET MVC 3 自定义显示模板 - 需要 For 循环吗?

目前,我已将流派列表添加到 ViewBag 中,然后在我的创建视图中循环浏览该列表:

@{
    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 中处理这个问题最有效的方法是什么?

I'm using Entity Framework Code First to generated my database, so I have an object defined like the following:

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

Now I'm looking at a create view for this and the default scaffolding isn't adding Genres to my form, which from past experience is about what I expect.

Looking online I've found Using ASP.NET MVC v2 EditorFor and DisplayFor with IEnumerable<T> Generic types which seems to come closest to what I want, but doesn't seem to make sense with Razor and possibly MVC 3, per ASP.NET MVC 3 Custom Display Template With UIHint - For Loop Required?.

At present I've added the listing of genres to the ViewBag and then loop through that listing in my create 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>

Outside of not yet handling cases where the user has JavaScript disabled and the checkboxes need to be re-checked, and actually updating the database with this information, it does output the genres as I'd like.

But this doesn't feel right, based on how good MVC 3 has become.

So what's the most effective way to handle this in MVC 3?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

迷路的信 2024-12-08 16:13:46

我不通过 ViewBag 将列表发送到我的视图中,而是使用我的视图模型来执行此操作。例如,我做了这样的事情:

我有一个这样的 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 中用于我的视图模型的 Toppings 属性中的每个配料。

然后我有一个视图模型,其中包括 Toppings 集合:

public IEnumerable<ToppingsViewModel> Toppings { get; set; }

在我的控制器中,除其他外,我检索了 toppings(但在我的情况下这样做)并将我的 viewmodel 的属性设置为该集合配料。在编辑的情况下,之前可能已经选择了配料,我设置 TopingsViewModel 的 IsChecked 成员,并将相应的复选框设置为选中。

这样做提供了正确的模型绑定,以便当用户检查一些配料时,集合中的底层项目会反映这些选择。对我来说效果很好,希望对你有帮助。

I don't send lists into my View via the ViewBag, instead I use my viewmodel to do this. For instance, I did something like this:

I have an EditorTemplate like this:

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

which I put in my Views\IceCream\EditorTemplates folder. I use this to display some html for allowing the user to "check" any particular topping.

Then in my View I've got something like this:

@HtmlEditorFor(model => model.Toppings)

and that will use that result in my EditorTemplate being used for each of the toppings in the Toppings property of my viewmodel.

And then I've got a viewmodel which, among other things, includes the Toppings collection:

public IEnumerable<ToppingsViewModel> Toppings { get; set; }

Over in my controller, among other things, I retrieve the toppings (however I do that in my case) and set my viewmodel's property to that collection of toppings. In the case of an Edit, where toppings may have been selected previously, I set the IsChecked member of the TopingsViewModel and it'll set the corresponding checkboxes to checked.

Doing it this way provided the correct model binding so that when the user checked a few toppings, the underlying items in the collection reflected those selections. Worked well for me, hope it's helpful for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文