【问题标题】:MVC 6 complex model bindingMVC 6 复杂模型绑定
【发布时间】:2016-03-07 19:47:06
【问题描述】:

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

父模型

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 的事情,因为据我所知,这应该可以工作?

谢谢

【问题讨论】:

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


    【解决方案1】:

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

    显式指定输入的名称属性值

    在主视图中,您可以使用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" 等。当您发布表单时,模型绑定将正常工作。

    使用编辑器模板

    您可以在~/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" 等。当您发布表单时,模型绑定将正常工作。

    【讨论】:

    • 谢谢 Shyju,感谢您在此处列出的详细信息。下午大部分时间都在阅读数据绑定并确定编辑器模板。
    • @AnthonySherratt 不客气!很高兴我能帮忙:)
    • 很棒的解释 @Shyju 你用你的例子帮我省了一大堆工作。
    • 信息量很大@Shyju。但是,我有一种情况,我需要在应该位于编辑器模板中的区域中使用MainVM. MainProperty1(我需要在asp-for="ChildModel.ChildPropertyX" 实例之间使用MainVM.MainProperty1)。因此,就我而言,我认为编辑器模板可能不起作用。还有其他方法吗?
    【解决方案2】:
    • why would this be dropped or missing

    它既没有掉落也没有丢失。因为子视图不会知道它的模型是否有任何父视图。它只会知道ChildVM是它的模型,name是它的属性,没有任何前缀。

    【讨论】:

    • 从我看到的例子中,他们是这样呈现的。也许我不了解父/子模型绑定的工作原理。你有一个例子说明我如何将我的子模型绑定到局部视图并仍然保持正确的绑定?
    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多