传递模型的IEnumerable属性到控制器后动作- ASP MVC
本文关键字:MVC ASP 控制器 模型 IEnumerable 属性 | 更新日期: 2023-09-27 17:52:41
我正在做一个asp-MVC应用程序,面临以下问题:下面是一个工作代码:
<div id="detailsTemplates">
@for (var i = 0; i < Model.Filter.itemDetails.Count; i++)
{
<table>
<tr>
<td>
@Html.TextBoxFor(model => model.Filter.itemDetails[i].iD)
</td>
</tr>
</table>
}
现在在我的控制器的post动作中,我得到了正确插入的值
现在,当我将代码更改为局部视图时:<div id="detailsTemplates">
@for (int i = 0; i < Model.Filter.itemDetails.Count; i++)
{
Html.RenderPartial("itemDetailsUserControl", Model.Filter.itemDetails[i]);
}
</div>
,部分视图如下所示:
<div id="detailsTemplates">
<table>
<tr>
<td>
@Html.TextBoxFor(item => item.iD)
</td>
</tr>
</table>
}
现在这个值不会通过post传递。
我做错了什么?
视图中模型的上下文来自传递给它的模型。例如,通过传递
Model.Filter.CustomsitemDetails[i]
您已经将根从Model对象更改为CustomiseDetails对象。(因此输入的名称将是"CustomsItemClassificationID"而不是"Filter.CustomsitemDetails[i]"。CustomsItemClassificationID",因此在发布时不会反弹,因为它将不再匹配它所绑定的属性。
正确的方法是使用编辑器模板。这将保留模型的起源。为此,在Views> Shared下创建一个名为EditorTemplates的文件夹。
将您的部分复制到其中,并将其重命名为您的类型的名称。例如,如果Model.Filter。CustomsitemDetails[i]是CustomsitemDetail,那么编辑器模板文件夹下的文件将被命名为CustomsitemDetails.cshtml。
现在,而不是
@Html.RenderPartial("CustomsItemDetailsUserControl", Model.Filter.CustomsitemDetails[i]);
使用@Html.EditorFor(m => m.Filter.CustomitemDetails[i])
所以我学到了一些新东西:
如果在控制器的EditorTemplates文件夹中找到与templateName参数匹配的模板,则使用该模板来呈现表达式。如果在控制器的EditorTemplates文件夹中没有找到模板,则在Views'Shared'EditorTemplates文件夹中搜索与templateName参数名称匹配的模板。如果未找到模板,则使用默认模板。 from MSDN.
所以,与我的答案的第二部分相反,你确实需要将你的部分移动到
"~/Areas/TaxCalculation/Views/Home/EditorTemplates/CustomsItemDetailsUserControl.cshtml"
和使用:
@Html.EditorFor(m => m.Filter.CustomitemDetails[i], "CustomsItemDetailsUserControl")
更新2
根据Stephen的评论- EditorFor()有一个接受IEnumerable的重载,所以你可以直接使用
@Html.EditorFor(m => m.Filter.CustomitemDetails, "CustomsItemDetailsUserControl")
或者如果您有一个名为CustomitemDetails的EditorTemplate。/Views/Shared/EditorTemplates/目录下的cshtml文件:
@Html.EditorFor(m => m.Filter.CustomitemDetails)