我正在研究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>
}
现在该值不通过帖子传输。
我做错了什么?
答案 0 :(得分:3)
视图中模型的上下文来自传递给它的模型。 例如。传递
Model.Filter.CustomsitemDetails[i]
对于您的部分,您已将Model对象的根目录更改为CustomiseDetails对象。 (因此输入的名称将是“CustomsItemClassificationID”而不是“Filter.CustomsitemDetails [i] .CustomsItemClassificationID”,因此在发布时不会反弹,因为它将不再匹配它所绑定的属性。
执行此操作的正确方法是使用编辑器模板。这将保留模型的起源。为此,请在Views&gt;下创建一个名为EditorTemplates的文件夹。共享。
将您的部分复制到其中,并将其重命名为您的类型名称。例如,如果Model.Filter.CustomsitemDetails [i]的类型是CustomsitemDetail,则编辑器模板文件夹下的文件将被称为CustomsitemDetails.cshtml。
现在,而不是
@Html.RenderPartial("CustomsItemDetailsUserControl", Model.Filter.CustomsitemDetails[i]);
使用
@Html.EditorFor(m => m.Filter.CustomitemDetails[i])
或者,如果您不想重命名或移动文件,可以改为指定它的当前位置:
@ Html.EditorFor(m =&gt; m.Filter.CustomitemDetails [i],“〜/ Views / {controller} /CustomsItemDetailsUserControl.cshtml”)
<强>更新强>
所以我学会了一些新东西:
如果在控制器的EditorTemplates文件夹中找到名称与templateName参数匹配的模板,则该模板用于呈现表达式。如果在控制器的EditorTemplates文件夹中找不到模板,则会在Views \ Shared \ EditorTemplates文件夹中搜索与templateName参数名称匹配的模板。如果未找到模板,则使用默认模板。来自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")
或者如果您在/ Views / Shared / EditorTemplates /文件夹中有一个名为CustomitemDetails.cshtml的EditorTemplate:
@Html.EditorFor(m => m.Filter.CustomitemDetails)