Asp.net mvc PartialView中的MVC多个表单在回发时返回空值,列出的第一个表单除外

Asp.net mvc PartialView中的MVC多个表单在回发时返回空值,列出的第一个表单除外,asp.net-mvc,partial-views,html-helper,model-binding,Asp.net Mvc,Partial Views,Html Helper,Model Binding,好的,我希望有人能在这方面帮助我(提前谢谢!)。我用的是MVC4 我的ContractsModel包含(除其他外)一个ContractModel列表。在我的局部视图中,我循环浏览列表,为每个列表创建一个表单。到现在为止,一直都还不错。这期正在回邮中。第一张表格总是贴得很好。但是其他的(2、3、4等)总是返回null 我已经使用调试工具进行了检查,并确认渲染的控件已正确命名 <select name="Contracts[0].OrganizationId" id="Contracts_0_

好的,我希望有人能在这方面帮助我(提前谢谢!)。我用的是MVC4

我的ContractsModel包含(除其他外)一个ContractModel列表。在我的局部视图中,我循环浏览列表,为每个列表创建一个表单。到现在为止,一直都还不错。这期正在回邮中。第一张表格总是贴得很好。但是其他的(2、3、4等)总是返回null

我已经使用调试工具进行了检查,并确认渲染的控件已正确命名

<select name="Contracts[0].OrganizationId" id="Contracts_0__OrganizationId">
<select name="Contracts[1].OrganizationId" id="Contracts_1__OrganizationId">
<select name="Contracts[2].OrganizationId" id="Contracts_2__OrganizationId">
这是我的部分观点

@model Manager.Models.ContractsModel

@for (int i = 0; i < Model.Contracts.Count(); i++)  
{
    var divId = "divContractsModelItem_" + (i + 1);
    var saveButtonId = "btnContractsEditSave_" + (i + 1);


    <div id = "@divId">  

        @using (Html.BeginForm("_ContractsEdit", "Projects", FormMethod.Post))
        {      
            <fieldset>
                <legend>General:</legend>

                <div>
                    <label>Contracting Organization:</label>
                    @Html.DropDownListFor(model => model.Contracts[i].OrganizationId, new SelectList(Model.OrganizationList, "value", "text", Model.Contracts[i].OrganizationId))
                </div>

                <div>
                    <label>Contract Number:</label>
                    @Html.DropDownListFor(model => model.Contracts[i].ContractNumId, new SelectList(Model.ContractNumList, "value", "text", Model.Contracts[i].ContractNumId))
                </div>

                <div>
                   <button id="@saveButtonId" type="submit">Save</button>
                </div>

            </fieldset>
        }
    </div> 

} 
@model Manager.Models.ContractsModel
@对于(int i=0;imodel.Contracts[i].OrganizationId,新选择列表(model.OrganizationList,“值”,“文本”,model.Contracts[i].OrganizationId))
合同编号:
@Html.DropDownListFor(model=>model.Contracts[i].ContractNumId,新选择列表(model.ContractNumList,“value”,“text”,model.Contracts[i].ContractNumId))
拯救
}
} 

乍一看,每个表单所表示的内容与post controller方法所期望的内容之间似乎存在脱节。看起来每个表单实例都代表一个契约,而您的控制器post方法需要一个完整的契约模型。也许可以尝试将控制器方法更改为只接受合同。

由于我的评论对您有所帮助,我想我会将其充实为完整的答案

模型绑定的问题在于它不允许跳过数组索引—一旦跳过一个索引,它就会停止绑定。您的页面有多个表单,每个表单对应一个合同。因此,第二个表单和后续表单不是从索引0开始的,而是从索引1开始,然后是索引2,依此类推。因此,模型绑定会立即失败,并将一个空对象传递到控制器中

简单的解决方案是移动到单个表单,以便模型绑定可以访问契约对象的所有索引,然后在控制器中使用额外的代码来确定按下了哪个提交按钮


尽管如此,我不确定这是最好的解决方案,因为它减少了发布到服务器的不必要数据量。然而,best是good的敌人,如果一个表单起作用……

我的猜测是,由于多个表单,您将遇到缺少索引的问题(请参阅)。但是,不确定在这种情况下解决问题的最佳方法是什么。(除了转到单个表单并确定按下了哪个提交按钮,从而保存了哪些合同信息的解决方案之外。)已经尝试过了。。。我的控制器仍然接收空值。有趣的是,第一个表单正确地返回了模型,随后的表单返回null。现在我想起来,这有点道理——运行时看到您正在回传合同[2]。。。但是合同[1]和合同[0]在哪里?对于第一个问题,没有问题——运行时可以知道该做什么。呈现许多内容和将一个内容发回包含许多内容的容器之间存在继承不匹配。这是有道理的。。。看来接受杰森的建议可能是最容易解决的问题。
[HttpPost]
public ActionResult _ContractsEdit(ContractsModel model)
{

    if (ModelState.IsValid) {
        //blah, blah, blah....
    }

    return PartialView("Index", ProjectModel);
}
@model Manager.Models.ContractsModel

@for (int i = 0; i < Model.Contracts.Count(); i++)  
{
    var divId = "divContractsModelItem_" + (i + 1);
    var saveButtonId = "btnContractsEditSave_" + (i + 1);


    <div id = "@divId">  

        @using (Html.BeginForm("_ContractsEdit", "Projects", FormMethod.Post))
        {      
            <fieldset>
                <legend>General:</legend>

                <div>
                    <label>Contracting Organization:</label>
                    @Html.DropDownListFor(model => model.Contracts[i].OrganizationId, new SelectList(Model.OrganizationList, "value", "text", Model.Contracts[i].OrganizationId))
                </div>

                <div>
                    <label>Contract Number:</label>
                    @Html.DropDownListFor(model => model.Contracts[i].ContractNumId, new SelectList(Model.ContractNumList, "value", "text", Model.Contracts[i].ContractNumId))
                </div>

                <div>
                   <button id="@saveButtonId" type="submit">Save</button>
                </div>

            </fieldset>
        }
    </div> 

}