【问题标题】:MVC - Editing a list of objectsMVC - 编辑对象列表
【发布时间】:2012-10-02 19:31:37
【问题描述】:

我在 MVC 中有以下类布局:

public class ReportModel 
{
    List<SomeItem> items;
    string value;
    string anotherValue;
}

现在我在这种类型的 MVC 中创建一个强类型视图,并制作可编辑的文本字段来编辑每个值,并使用 foreach 循环填充文本字段以编辑某些项目列表中的项目。

当我提交给 httppost 方法时,奇异值在 reportmodel 对象中恢复正常,但列表没有在对象中返回。这应该怎么做?

当我说 httppost 时,我指的是 MVC 发回的方法

[HttpPost]
public ActionResult EditReport(ReportModel report)
{
    // Save the report in here after the update on the UI side
}

查看发布某项列表的代码

if (Model.items != null && Model.items.Count > 0)
{
    for (int i = 0; i < Model.items.Count; i++)
    {                
        <div class="editrow">
            <div class="edititem">
                <div class="editor-label">
                    @Html.LabelFor(m => m.items.ElementAt(i).propertyOne)
                </div>
                <div class="editor-field">
                    @Html.TextBoxFor(m => m.items.ElementAt(i).propertyOne)
                    @Html.ValidationMessageFor(m => m.items.ElementAt(i).propertyOne)
                </div>
            </div>
            <div class="edititem">
                <div class="editor-label">
                    @Html.LabelFor(m => m.items.ElementAt(i).propertyTwo)
                </div>
                <div class="editor-field">
                    @Html.TextBoxFor(m => m.items.ElementAt(i).propertyTwo)
                    @Html.ValidationMessageFor(m => m.items.ElementAt(i).propertyTwo)
                </div>
            </div>
            <div class="edititem">
                <div class="editor-label">
                    @Html.LabelFor(m => m.items.ElementAt(i).propertyThree)
                </div>
                <div class="editor-field">
                    @Html.TextBoxFor(m => m.items.ElementAt(i).propertyThree)
                    @Html.ValidationMessageFor(m => m.items.ElementAt(i).propertyThree)
                </div>
            </div>
        </div>
    }
}

【问题讨论】:

  • 第一:吹毛求疵:在标题中:列表,未点亮。第二:你说的httppost方法是什么?我们在这里谈论Android吗?请添加该标记以表示它。
  • 你读到了吗:hanselman.com/blog/…
  • @KirillBestemyanov 这不是我想要的,因为我希望将它们返回到报告模型中,而不是作为函数的单独参数
  • @bldoron nitpicking 肯定:P haha​​ 更新了标题并详细说明了 httppost 的含义(我认为标题中的 MVC 会暗示将帖子返回到 httppost 方法,我为错误传达道歉)
  • 您需要包含显示您如何呈现列表的视图代码。没有它,我们不知道它是以什么格式发布的。

标签: asp.net-mvc http-post


【解决方案1】:

不要在你的 lambda 表达式中使用 ElementAt(1) => 这会破坏你的输入字段名称。请阅读 Kirill 建议您的博文。

所以你可以使用索引访问:

for (int i = 0; i < Model.items.Count; i++)
{                
    <div class="editrow">
        <div class="edititem">
            <div class="editor-label">
                @Html.LabelFor(m => m.items[i].propertyOne)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.items[i].propertyOne)
                @Html.ValidationMessageFor(m => m.items[i].propertyOne)
            </div>
        </div>
        <div class="edititem">
            <div class="editor-label">
                @Html.LabelFor(m => m.items[i].propertyTwo)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.items[i].propertyTwo)
                @Html.ValidationMessageFor(m => m.items[i].propertyTwo)
            </div>
        </div>
        <div class="edititem">
            <div class="editor-label">
                @Html.LabelFor(m => m.items[i].propertyThree)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.items[i].propertyThree)
                @Html.ValidationMessageFor(m => m.items[i].propertyThree)
            </div>
        </div>
    </div>
}

当然,为了让索引器访问集合,这假定您的 items 属性声明为 List&lt;SomeItem&gt;SomeItem[]。如果它是IEnumerable&lt;SomeItem&gt;,它将不起作用。因此,只需在视图模型上更改此属性的类型即可。

【讨论】:

  • hmm 我认为我的是一个 IEnumerable,因为我使用的是一个直接传递给视图的实体对象,我相信它期待一个 IEnumerable。基本上我必须创建一个模型视图对象,这是不可取的,因为我的对象中有大约 180 个字段(没有选择减少它,因为它不是我的项目哈哈)。
  • 您的表单上有 180 个字段并且视图都需要这些字段?如果是这种情况,那么使用视图模型确实不会带来太多好处。因此,在这种情况下,您可以使用自定义编辑器模板。不要在视图中编写任何for 循环。只需用@Html.EditorFor(x =&gt; x.items) 替换整个循环,然后为SomeItem 类定义自定义编辑器模板-~/Views/Shared/EditorTemplates/SomeItem.cshtml。 ASP.NET MVC 将为 items 集合的每个元素自动调用此自定义模板,因此该模板将被强类型化为 @model SomeItem
  • 然后在自定义模板中放置带有 div 的标记并使用以下表达式:@Html.TextBoxFor(x =&gt; x.propertyOne), ...。在这种情况下,助手将为输入字段生成正确的名称。
  • 是的,我一直在研究这个作为解决方案,目前我已经被转移到一个 dif 项目中,稍后在我同时兼顾这两个项目时将不得不返回这个项目。感谢您的建议,我对 MVC 非常陌生,因此使用视图模型更加熟悉并且认为它会起作用。很高兴我现在知道这一点,因为“EditorFor”似乎是一种非常有用的展示方式,并且可以节省时间!
【解决方案2】:

Kirill 对 Scott Hanselman 博客条目的引用是正确的,但您的阅读范围太窄了。在显示的示例中,他将数组传递给 action 方法,但它也可以很容易地包含在父模型中。同样的概念也适用。

但是,要知道的一件事是,默认模型绑定器不会实例化嵌套类,因此它不会创建 List 类的实例,这意味着它将始终为空。要解决此问题,您必须在构造函数中实例化空列表类。

这只是问题的一部分,因为数据必须以正确的方式格式化,模型绑定器才能绑定它。这就是 Scott 的博客文章的用武之地,因为它提供了模型绑定器将数据识别为列表所需的格式。

如果您使用 EditorTemplate 并使用 Html.EditorFor(m => m.Items) 然后有 SomeItem.cshtml EditorTemplate,这通常会为您处理。这涉及到集合项命名的问题(只要您也在模板中使用强类型的帮助器)。

【讨论】:

    猜你喜欢
    • 2021-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 2021-11-16
    • 1970-01-01
    • 2011-02-02
    相关资源
    最近更新 更多