更改表单上下文以确保嵌套模型正确命名?

时间:2015-08-21 14:41:22

标签: c# asp.net-mvc razor asp.net-mvc-5

在RoR中,您可以更改表单上下文,以便正确构建表单元素ID和名称(例如simple_fields_for myModel do |innerModel|或类似名称)。我想知道用MVC5做这个的正确方法是什么。例如......

模型

class Model1 {
    public Model2 M2 { get; set; }
}

class Model2 {
    public List<Model3> M3s { get; set; }
}

class Model3 {
    public string Name { get; set; }
}

控制器

class MyController {
    public ActionResult Test(Model1 model) {
        View(model);
    }
}

查看

@model Model1

@using (MvcForm form = Html.BeginForm()) {
    Html.RenderPartial("_Model2", this.Model.M2);
}

如果回发3 Model3个实例,则模型状态应类似于:

M2.M3s[0].Name=Name1
M2.M3s[1].Name=Name2
M2.M3s[2].Name=Name3

在这种情况下,视图使用部分呈现Model2,但部分不知道它在this.Model.M2的上下文中,因此不会为生成的id和名称添加前缀Model2. - 它只是以Model3启动它们。解决方案是使用新的表单上下文(不是字面意思FormContext),如下所示:

@using (MvcForm form = Html.BeginForm()) {
    using (form.For(m => m.M2)) {
        Html.RenderPartial("_Model2", this.Model.M2);
    }
}

请注意,form.For不存在,但其目的是将当前ModelMetadata更改为具有M2的相应上下文和前缀。因此,在该块内呈现的任何内容都将继承该新上下文,并且将正确生成ID和名称。

1 个答案:

答案 0 :(得分:2)

您可以在调用RenderPartial时实际指定前缀,然后部分视图字段的表单值将自动接收该前缀:

Html.RenderPartial("_Model2", this.Model.M2, new ViewDataDictionary
{
    TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "M2" }
})