MVC 6复杂模型绑定

时间:2015-12-03 09:13:15

标签: viewmodel model-binding asp.net-core-mvc

我正在尝试实现复杂的视图模型并将其绑定到表单。不幸的是,绑定似乎丢失/错过了子模型前缀,因此当我尝试提交模型时,模型绑定器不知道如何解释数据。这是代码的简化版本......

家长模式

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的东西,因为据我所知,这应该有效吗?

由于

2 个答案:

答案 0 :(得分:3)

这是预期的行为。如果您希望保持视图模型结构不变并仍希望模型绑定工作,您可以尝试以下任一解决方案。

明确指定输入的名称属性值

在主视图中,您可以使用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属性的输入字段,例如name="ChildModel.ChildProperty1"name="ChildModel.ChildProperty2"等。当您发布表单时,模型绑定将正常工作。

使用编辑器模板

您可以在EditorTemplates下创建一个名为~/Views/YourCurrentControllerName的新目录,并在其下创建一个名为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属性的输入字段,例如name="ChildModel.ChildProperty1"name="ChildModel.ChildProperty2"等。当您发布表单时,模型绑定将正常工作。

答案 1 :(得分:0)

  • datagridview

既不丢弃也不丢失。因为子视图不会知道它的模型是否有父母。它只会知道 Dim n As Integer = 'Datagridview cell value' Dim mon As Integer = Convert.ToInt32(n.ToString.Substring(0, 1)) Dim dt As Integer = Convert.ToInt32(n.ToString.Substring(1, 2)) Dim yr As Integer = Convert.ToInt32(n.ToString.Substring(3, 4)) Dim dt1 As New DateTime(yr, mon, dt) 是它的模型,而BufferedImage image = ImageIO.read(new File("image-path")); JLabel label = new JLabel(new ImageIcon(image)); panel.add(label); 它的属性没有任何前缀。