MVC将子模型发布到控制器

时间:2016-04-04 16:08:31

标签: c# asp.net-mvc

我有一个父视图模型(我们称之为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>
    }
}

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

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

}

表单工作并提交但是当ChildViewModel到达提交控制器时为空。这当然是因为Form Post和Action之间的绑定没有发生。

2 个答案:

答案 0 :(得分:3)

I am afraid it is not possible to post the child model only , since the page can define one and only one model that is the parent model you have defined .

But you can solve your problem simply by posting the parent model and extracting the child model in the controller .

答案 1 :(得分:1)

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

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

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

<input name="SomeProperty" ../>

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

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

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

注意m的属性表达式中忽略HiddenFor。我想上次我这样做时变量名必须匹配动作的参数名,所以你要将它提交给:

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

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