MVC 5 BeginCollectionItem模型始终为空

时间:2016-10-06 15:43:42

标签: c# asp.net-mvc

试图使用Html.BeginCollectionItem在我的应用程序中工作,并且正在努力使数据发布。我想将项目添加到列表中,然后发布整个列表。我使用ajax和jquery添加和删除项目到我的列表,这似乎是有效的。但是当我发布在我的控制器中收到的模型总是为空时,即使我看到提琴手,表格数据包含我的所有信息。

有人在我的代码中看到一些我做错了吗?

主要观点:

@model Test.Models.TestList

@using (Html.BeginForm())
{

<div class="form-group">
    <div class="row">
        <label for="AssemblyText" class="col-sm-1 col-sm-offset-1 control-label">Assembly:</label>
        <div class="col-sm-2">
           <input type="text" id="assembly" />
        </div>
        <label for="QuantityText" class="col-sm-1 control-label">Quantity:</label>
        <div class="col-sm-2">
            <input type="text" id="Qty" />
        </div>
        <button type="button" id="AddAssembly">Add Button</button>
    </div>
</div>

<table id="Assemblies" class="table table-striped">
<thead>
    <tr>
        <th>Assembly</th>
        <th>Quantity</th>
        <th>Action</th>
    </tr>
</thead>
<tbody class="text-left">
        @if (Model != null)
        {
            foreach (var assembly in Model.mylist)
            {
                @Html.Partial("AssemblyRow", assembly)
            }
        }
</tbody>   
</table>
<div class="form-group">
    <input type="submit" id="submitbtn" class="btn btn-success" value="Submit" />
</div>
}

部分视图(AssemblyRow)

@model Test.Models.Test

<tr class="editorRow">
@using (Html.BeginCollectionItem("Assembly"))
{
<td>
    @Html.HiddenFor(m => m.assembly)
    @Html.TextBoxFor(m => m.assembly)    
</td>
<td>
    @Html.HiddenFor(m => m.Qty)
    @Html.TextBoxFor(m => m.Qty)
</td>
<td>
    <span class="dltBtn">
        <a href="#" class="deleteRow">Delete</a>
    </span>
</td>
}

我的模特很简单,看起来像......

public class TestList
{
    public List<Test> mylist { get; set; }
}


public class Test
{
    public string assembly { get; set; }
    public string Qty { get; set; }

}

我的控制器

    [HttpPost]
    public ActionResult PostMain(TestList model)
    {


        return View();
    }

我可以提供你认为有用的其他代码,但我试着用我认为相关的部分来保持简单。

感谢您的帮助!

编辑:fiddler的图片

enter image description here

3 个答案:

答案 0 :(得分:1)

您的集合属性名为mylist,因此您必须将该名称传递给BeginCollectionItem方法

@using (Html.BeginCollectionItem("mylist"))
{
    ....

将生成name=mylist[xxxx].assembly"(其中xxxxGuid)的元素,这些元素需要正确绑定到您的模型。

但是,您的代码还有其他问题。 DefaultModelBinder绑定与模型属性匹配的第一个名称/值对,并忽略具有相同名称的任何后续名称/值对。因为在文本框之前为每个属性都有一个隐藏输入,所以在提交时只会绑定发送到视图的初始值,而不是编辑的值。您需要删除部分为

的隐藏输入
@model Test.Models.Test
<tr class="editorRow">
    @using (Html.BeginCollectionItem("mylist"))
    {
        <td>@Html.TextBoxFor(m => m.assembly)</td>
        <td>@Html.TextBoxFor(m => m.Qty)</td>
        <td>
            <span class="dltBtn"><a href="#" class="deleteRow">Delete</a></span>
        </td>
    }
</tr>

旁注:还不清楚初始<div class="form-group">中的html是什么。你包括2个输入和一个按钮,但不会绑定到你的模型,也不会正确地将项添加到你的集合中(你的添加按钮需要使用ajax来调用返回另一个局部视图的服务器方法并将其附加到DOM)

答案 1 :(得分:0)

我没有看到提交按钮,因此无法确切地告诉您提交的内容,但请尝试将ActionResult PostMain(TestList model)更改为:

ActionResult PostMain(List<Test> model)

答案 2 :(得分:-1)

您需要使用编辑器模板而不是部分视图。部分视图中不提供主控制器上下文。 Stackoverflow上有很多帖子在讨论这个问题。其中之一是 ASP.NET MVC 3 - Partial vs Display Template vs Editor Template