Razor部分视图前缀字段名

3
当使用Razor渲染一个包含子模型的复杂模型的表单时,通常会使用Partial View来渲染子模型。
简单的示例模型:
public class BlogPost
{
    public string Content { get; set; }
    public List<Comment> Comments { get; set; }
}

public class Comment
{
    public string Content { get; set; }
}

BlogPost.cshtml:

@model BlogPost

@Html.TextAreaFor(x => x.Content)

@for (int i = 0; i < Model.Comments.Count; i++)
{
    @Html.Partial('Comment', Model.Comments[i])
}

Comment.cshtml:

@model Comment

@Html.TextAreaFor(x => x.Content)

现在来说这个问题:

假设我们想要将所有字段的值发送到一个控制器操作,该操作以BlogPost作为参数。字段将像下面这样被提交到控制器:

Content=The+content+of+the+BlogPost&Content=The+first+Comment&Content=The+second+Comment

但是,为了使MVC能够正确地将它们映射到BlogPost视图模型,我们需要遵循这种命名约定:

Content=The+content+of+the+BlogPost&Comments[0].Content=The+first+Comment&Comments[1].Content=The+second+Comment

有什么干净的方法可以实现这一点吗? 我们只能想到两种方式,它们似乎都会损害设计:

  • 要么我们将BlogPost作为模型传递给部分视图,以便我们可以像这样定义文本区域:@Html.TextAreaFor(x => x.Comments[i].Content)。 但这意味着我们将评论的部分视图与父视图模型耦合 - 您可以想象应该在不同上下文中使用相同的部分视图的情况,如果部分视图取决于父视图模型,则不可能实现。 此外,i必须以某种方式传递给部分视图。
  • 或者我们回退到使用字符串显式定义每个字段的名称:@Html.TextArea(ViewBag.Prefix + ".Content")

有没有办法告诉部分视图将某个前缀应用于所有字段名称?

1个回答

2

chiccodoro,

如果您创建了一个类型为Comment的EditorFor模板,mvc会为您处理所有这些美丽的事情。然而,在已经存在于数据库中的情况下,这只能很好地工作。例如来自SO:

提交父母和子女在剃刀中

如果您需要在运行时创建新行,则必须使用一些诡计来允许字段按要求操作。我使用了Steven Sanderson网站上的一篇文章,该文章允许您在运行时添加集合项并仍保留非侵入式验证等。请参见此SO问题和相关文章引用:

使用表格编辑可变长度列表,ASP.NET MVC 3样式


谢谢,EditorFor 是关键!同时很高兴阅读到 Steven-Sanderson 的一些提示,以便处理新行。 - chiccodoro
chiccodoro - 很高兴解决了你的困惑。Steven Sanderson的东西确实比我能说的次数更多地拯救了我的生命。 - jim tollan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接