【问题标题】:Change form context to ensure nested models are named correctly?更改表单上下文以确保正确命名嵌套模型?
【发布时间】:2015-08-21 14:41:21
【问题描述】:

在 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 的上下文中,因此不会为使用Model2. 生成的ID 和名称添加前缀- - 它只是以Model3 开头。解决方案是使用新的表单上下文(不是字面意思FormContext),如下所示:

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

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

【问题讨论】:

  • 更容易的是你使用EditorTemplate而不是部分,它将正确添加前缀(将你的部分重命名为/Views/Shared/EditorTemplates/Model2.cshtml(以匹配类型),然后在视图中使用@Html.EditorFor(m =&gt; m.M2)

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


【解决方案1】:

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

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

【讨论】:

  • 谢谢,我确实找到了这个答案(当然是在我输入了所有这些之后,即使我之前试图找到答案),这表明了类似的方法:stackoverflow.com/questions/1488890/… 我会写一个帮助使这更直接和无缝!
  • @JoshM。没问题,是的,实际上将它包装在 HTML 辅助方法中非常方便。
  • 这很好用,但肯定很麻烦。让我现在继续前进,谢谢!我很惊讶没有内置的助手来处理这种情况,这似乎很常见,因为我经常遇到这种情况。另一种更烦人的解决方法是为模型链中的每个“步骤”设置一个编辑器模板/部分。但这太过分了。
  • @JoshM。是的,它仍然是框架中的一个缺点。另一种选择是将父模型传递给每个部分,这也不理想。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多