MVC 6 复杂模型绑定
MVC 6 complex model binding
我正在尝试实现一个复杂的视图模型并将其绑定到一个表单。不幸的是,绑定似乎是 drop/miss 子模型前缀,所以当我尝试将模型提交回去时,模型绑定器不知道如何解释数据。这是代码的简化版本...
父模型
public class MainVM
{
public bool MainProperty1 { get; set; }
public ChildVM ChildModel { get; set; }
}
童模
public class ChildVM
{
public int ChildProperty1 { get; set; }
public string ChildProperty2 { get; set; }
public string ChildProperty3 { get; set; }
}
index.cshtml
@model MainVM
<form id="main-form" asp-controller="main" asp-action="submit" method="post">
<div>
@await Html.PartialAsync("partial", Model.ChildModel)
</div>
</form>
partial.cshtml
@model ChildVM
<div>
<input asp-for="ChildProperty1" />
<input asp-for="ChildProperty2" />
<input asp-for="ChildProperty3" />
</div>
输出
<form id="main-form" method="post" action="/main/submit">
<div>
<div>
<input type="text" data-val="true" name="ChildProperty1" data-val-maxlength-max="17" data-val-minlength-min="4" id="ChildProperty1" />
<input type="text" data-val="true" name="ChildProperty2" data-val-maxlength-max="50" data-val-minlength-min="3" id="ChildProperty2" />
<input type="text" data-val="true" name="ChildProperty3" data-val-maxlength-max="50" data-val-minlength-min="3" id="ChildProperty3" />
</div>
</div>
</form>
如您所见,name 属性上的绑定缺少 ChildVM
的前缀(例如 name="ChildVM.ChildProperty1"
)我的问题是为什么它会被删除或丢失?不确定我遗漏了什么,或者这是否是 MVC6 的东西,因为据我所知,这应该可以正常工作?
谢谢
why would this be dropped or missing
既没有掉落也没有丢失。因为子视图不会知道它的模型是否有任何父视图。它只知道 ChildVM
是它的模型,name
它是没有任何前缀的属性。
这是预期的行为。如果您想保持视图模型结构不变,并且仍然希望模型绑定起作用,您可以尝试以下任一解决方案。
明确指定输入的名称属性值
在主视图中,您可以使用 asp-for
标签
明确指定您的输入表单用于模型的子 属性
@model MainVM
<form id="main-form" asp-controller="main" asp-action="submit" method="post">
<input asp-for="MainProperty1" />
<div>
<h5>Child items</h5>
<input asp-for="ChildModel.ChildProperty1"/>
<input asp-for="ChildModel.ChildProperty2"/>
<input asp-for="ChildModel.ChildProperty3"/>
</div>
<input type="submit"/>
</form>
这将生成名称为 属性 的输入字段,例如 name="ChildModel.ChildProperty1"
和 name="ChildModel.ChildProperty2"
等。当您 post 表单时,模型绑定将正常工作。
使用编辑器模板
您可以在 ~/Views/YourCurrentControllerName
下创建一个名为 EditorTemplates
的新目录,并在其下创建一个名为 ChildVM.cshtml
的新视图,然后将以下代码粘贴到
@model ChildVM
<div>
<input asp-for="ChildProperty1"/>
<input asp-for="ChildProperty2"/>
<input asp-for="ChildProperty3"/>
</div>
并且在主视图中,使用Html.EditorFor
辅助方法
@model MainVM
<form id="main-form" asp-controller="main" asp-action="submit" method="post">
<input asp-for="MainProperty1" />
@Html.EditorFor(s => s.ChildModel)
<input type="submit"/>
</form>
这还将生成名称为 属性 的输入字段,例如 name="ChildModel.ChildProperty1"
和 name="ChildModel.ChildProperty2"
等。当您 post 表单时,模型绑定将正常工作。
我正在尝试实现一个复杂的视图模型并将其绑定到一个表单。不幸的是,绑定似乎是 drop/miss 子模型前缀,所以当我尝试将模型提交回去时,模型绑定器不知道如何解释数据。这是代码的简化版本...
父模型
public class MainVM
{
public bool MainProperty1 { get; set; }
public ChildVM ChildModel { get; set; }
}
童模
public class ChildVM
{
public int ChildProperty1 { get; set; }
public string ChildProperty2 { get; set; }
public string ChildProperty3 { get; set; }
}
index.cshtml
@model MainVM
<form id="main-form" asp-controller="main" asp-action="submit" method="post">
<div>
@await Html.PartialAsync("partial", Model.ChildModel)
</div>
</form>
partial.cshtml
@model ChildVM
<div>
<input asp-for="ChildProperty1" />
<input asp-for="ChildProperty2" />
<input asp-for="ChildProperty3" />
</div>
输出
<form id="main-form" method="post" action="/main/submit">
<div>
<div>
<input type="text" data-val="true" name="ChildProperty1" data-val-maxlength-max="17" data-val-minlength-min="4" id="ChildProperty1" />
<input type="text" data-val="true" name="ChildProperty2" data-val-maxlength-max="50" data-val-minlength-min="3" id="ChildProperty2" />
<input type="text" data-val="true" name="ChildProperty3" data-val-maxlength-max="50" data-val-minlength-min="3" id="ChildProperty3" />
</div>
</div>
</form>
如您所见,name 属性上的绑定缺少 ChildVM
的前缀(例如 name="ChildVM.ChildProperty1"
)我的问题是为什么它会被删除或丢失?不确定我遗漏了什么,或者这是否是 MVC6 的东西,因为据我所知,这应该可以正常工作?
谢谢
why would this be dropped or missing
既没有掉落也没有丢失。因为子视图不会知道它的模型是否有任何父视图。它只知道 ChildVM
是它的模型,name
它是没有任何前缀的属性。
这是预期的行为。如果您想保持视图模型结构不变,并且仍然希望模型绑定起作用,您可以尝试以下任一解决方案。
明确指定输入的名称属性值
在主视图中,您可以使用 asp-for
标签
@model MainVM
<form id="main-form" asp-controller="main" asp-action="submit" method="post">
<input asp-for="MainProperty1" />
<div>
<h5>Child items</h5>
<input asp-for="ChildModel.ChildProperty1"/>
<input asp-for="ChildModel.ChildProperty2"/>
<input asp-for="ChildModel.ChildProperty3"/>
</div>
<input type="submit"/>
</form>
这将生成名称为 属性 的输入字段,例如 name="ChildModel.ChildProperty1"
和 name="ChildModel.ChildProperty2"
等。当您 post 表单时,模型绑定将正常工作。
使用编辑器模板
您可以在 ~/Views/YourCurrentControllerName
下创建一个名为 EditorTemplates
的新目录,并在其下创建一个名为 ChildVM.cshtml
的新视图,然后将以下代码粘贴到
@model ChildVM
<div>
<input asp-for="ChildProperty1"/>
<input asp-for="ChildProperty2"/>
<input asp-for="ChildProperty3"/>
</div>
并且在主视图中,使用Html.EditorFor
辅助方法
@model MainVM
<form id="main-form" asp-controller="main" asp-action="submit" method="post">
<input asp-for="MainProperty1" />
@Html.EditorFor(s => s.ChildModel)
<input type="submit"/>
</form>
这还将生成名称为 属性 的输入字段,例如 name="ChildModel.ChildProperty1"
和 name="ChildModel.ChildProperty2"
等。当您 post 表单时,模型绑定将正常工作。