【问题标题】:MVC Post A Child model to a ControllerMVC 将子模型发布到控制器
【发布时间】:2016-04-04 16:08:30
【问题描述】:

我有一个父视图模型(我们称之为 ParentViewModel),它有一个子视图模型列表(我们称之为 ChildViewModel)。每个子视图模型都可以独立编辑,并且我有一个单独的表单,可以循环显示。这非常有效,但我无法弄清楚如何只发布子模型而忽略父模型。

这是我的表格:

@model ParentViewModel

...

@foreach (var child in Model.Children)
{
    @using (Html.BeginForm("_EditChild", "Admin", FormMethod.Post))
    {
        @Html.AntiForgeryToken()
        <div class="form-group">
            @Html.EditorFor(model => child.Content, new {htmlAttributes = new {@class = "form-control"}})
            @Html.ValidationMessageFor(model => child.Content, "", new {@class = "text-danger"})
        </div>
        <div class="form-group">
            <div class="col-md-12">
                <input type="submit" value="Create" class="btn btn-default new-post" />
            </div>
        </div>
    }
}

这是我的控制器的签名。它期望作为列表存在于 ParentViewModel 中的类型 ChildViewModel。

[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult _EditPost([Bind(Include = "")] ChildViewModel childViewModel)
{

}

表单工作并提交,但 ChildViewModel 在到达提交控制器时为空。这肯定是因为 Form Post 和 Action 之间没有绑定。

【问题讨论】:

  • BeginForm 调用中的 _EditChild 是什么?
  • 可能会移动@使用更高? @using...@foreach...*
  • 首先,您不能在foreach 循环内生成表单控件(请参阅this answer 以获得解释)。但是您一次只能发回一个表单,因此为每个项目创建一个表单是没有意义的。在一个表单中生成所有控件,以便您可以一次编辑和回发所有更改,或者提供指向另一个页面的链接来编辑您的子项目。

标签: c# asp.net-mvc


【解决方案1】:

恐怕不能只发布子模型,因为页面可以定义一个且只有一个模型是您定义的父模型。

但是你可以简单地通过在控制器中发布父模型并提取子模型来解决你的问题。

【讨论】:

    【解决方案2】:

    这是可能的,只是 ASP.NET MVC 不打算这样做。您所要做的就是从客户端提交的输入名称中删除父前缀。您的输入可能类似于:

    <input name="Children[0].SomeProperty" ../>
    

    如果您的 AdminController._EditChild 操作需要 ChildViewModel,那么您只需使用 javascript 将输入重命名为:

    <input name="SomeProperty" ../>
    

    并且模型绑定器应该构建 ChildViewModel。或者,您也可以通过创建将输入映射到 ChildViewModel 的自定义 ValueProvider 或 ModelBinder 来解决它,即使它具有错误的前缀……尽管这对我来说似乎比更改输入名称更丑陋。在这一点上,我可能还会在更新名称时使用 javascript 更新 ID,以使它们保持同步,即使只有名称用于绑定。

    另请注意,如果您不是循环,而只是想提交模型的单个子 ViewModel,则可以将其分配给一个变量:

    @var childVM = Model.ChildProp;
    @Html.HiddenFor(m => childVM.ID)
    

    注意mHiddenFor 的属性表达式中被忽略。我认为上次我这样做时,变量名称必须与操作的参数名称匹配,因此您可以将其提交给:

    public ActionResult SomeAction(ChildViewModel childVM){ ... }
    

    我目前正在尝试理解why this technique can't be combined with looping

    【讨论】:

      猜你喜欢
      • 2013-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-22
      • 1970-01-01
      • 2015-11-22
      • 2016-04-11
      相关资源
      最近更新 更多