在MVC 3中编辑多个项目的正确方法是什么?

时间:2012-02-21 05:11:45

标签: asp.net-mvc-3 multiple-instances

我有一个基类Product(properties:int ProductID,string Name,decimal Price)和一些基于产品的实例类型,例如:硬盘有其他属性。

我在单个视图中尝试编辑,其中包含基于产品列表的模型:

@model List<Product>

此视图只有一个编辑器声明:

@Html.EditorForModel(Model)

我为Product类创建了一个编辑器模板,它是一个Ajax表单,允许用户编辑每个产品的名称:

@model Product
@{
    // set unique IDs for result divs
    var resultDiv = "result" + Model.ProductID.ToString();
}
@using (Ajax.BeginForm("Update", new AjaxOptions
{
    HttpMethod = "POST",
    LoadingElementId = "working",
    UpdateTargetId = @resultDiv,
    InsertionMode = InsertionMode.Replace
}
))
{
    <div style="padding: 4px; margin-bottom: 4px; border: 1px solid gray; background-color: #eee;">
        @Html.HiddenFor(m => m.ProductID)
        @Html.DisplayFor(m => m.Name)
        @Html.LabelFor(m => m.Name)
        @Html.EditorFor(m => m.Name)
        <input type="submit" value="Save" />
        <span id="@resultDiv">...</span>
    </div>

}

这适用于第一行(ID [0] .Name)将使用单个条目发送数据。但是,编辑第二行或第三行会在帖子上产生空数据。

3 个答案:

答案 0 :(得分:2)

你应该看看下面的文章

Model Binding To A List

答案 1 :(得分:1)

在这里找出原因和解决方案 - “模型绑定到列表”链接对于阅读非常有用。

这里的问题是模型绑定器假设索引将从零开始并继续。每个项目生成的名称遵循以下模式:

[0].ProductID, [0].Name
[1].ProductID, [1].Name
[2].ProductID, [2].Name

但是,因为我使用单个AJAX表单为每个条目提交,所以如果我编辑了第一个项目([0]),模型绑定器只能从索引创建一个有效列表。

如果我编辑了第二个项目,表单帖子只有[1] .ProductId和[1] .Name的值 - 所以它不是从零开始的索引 - 所以活页夹无法重新创建产品数据 - - 因此为空值。

我的解决方案是将POST视为真实的 - 对单个对象进行单一编辑。为此,我需要将每个控件上的“name”属性更改为“ProductID”和“Name”,然后修改处理POST的Update方法以期望单个Product类型。

然后完美无缺。

答案 2 :(得分:0)

我们需要为每个项目提供一个索引来绑定复杂的对象。

<% for (int i = 0; i < Product.count; i++) { %>

 <%: Html.HiddenFor(m => m[i].ProductID) %>

  <%: Html.TextBoxFor(m => m[i].Name) %>

<%: Html.TextBoxFor(m => m[i].Price) %> 

<% } %>

如果您使用模板化助手,请在主视图页中使用如下所示的模式

<% for (int i = 0; i < Product.count; i++) { %>

  <%: Html.EditorFor(m => m[i]) %>

<% } %>

在Product.ascx(部分页面或模板助手)

 <%@ Control Inherits="ViewUserControl<Product>" %>

 <%: Html.HiddenFor(m => m[i].ProductID) %>

      <%: Html.TextBoxFor(m => m[i].Name) %>

    <%: Html.TextBoxFor(m => m[i].Price) %>