我正在使用net core 2.2开发一个Web MVC应用程序。
我有以下课程:
public class A
{
public IList<B> Bs { get; set; }
}
public class B
{
public string Id { get; set; }
public string Name { get; set; }
}
以下观点:
@model A
@for (int i = 0; i < Model.Bs.Count; i++)
{
<partial name="_BsPatialView" for="Bs[i]" />
}
以及部分视图(_BsPatialView.cshtml):
<input type='hidden' asp-for="@Model.Id" />
<input asp-for="@Model.Name" />
直到这里,它生成的一切都很好。部分视图中创建的输入的示例是:
<input type="hidden" id="Bs_3__Id" name="Bs[3].Id" />
<input type="text" id="Bs_3__Name" name="Bs[3].Name" />
使用元素名称和ID,控制器中的模型绑定器可以正确绑定所有内容。
问题是当我尝试从控制器返回局部视图时。我所做的是:
public IActionResult AddBElement(A a)
{
a.Bs.Add(new B() { Id = Guid.NewGuid() });
return PartialView("_BsPatialView", a.Bs.Last());
}
生成的html是:
<input type="hidden" id="Id" name="Id" />
<input type="text" id="Name" name="Name" />
那么,当我提交这些输入所在的表单时,模型绑定失败。
那么,我应该如何从控制器返回局部视图来解决这个问题呢?是否有任何等效的部分标签助手for
属性在控制器上使用?
模型绑定使用字段名称将它们映射到模型属性。现在因为你的名字不包含任何有关父类的信息,A
,模型绑定器不知道如何绑定它们。
换句话说,模型绑定器将知道如何绑定此输入:
<input type="hidden" id="Bs_3__Id" name="A.Bs[3].Id" />
但不是这个输入:
<input type="hidden" id="Bs_3__Id" name="Bs[3].Id" />
一种解决方案是将前缀A
传递给局部视图:See this answer
更好的解决方案是使用EditorTemplate
而不是Partial View,这将为您的输入字段生成正确的名称。要使用EditorTemplate
将部分视图重命名为B.cshtml(这应该是您的类名)并将其放在/Views/Shared/EditorTemplates
文件夹下...然后您可以像这样使用它:
@Html.EditorFor(m => m.Bs)