Razor局部视图前缀字段名称



当使用Razor为具有子模型的复杂模型渲染窗体时,我们通常会使用局部视图来渲染子模型。

简单示例模型:

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=+内容+的+博客文章&内容=+第一个+注释&内容=+秒+评论

但是,我们需要MVC将它们正确映射到BlogPost视图模型,我们需要这样的命名约定:

Content=+内容+的+博客文章&Comments[0].Content=+第一个+Comment&Comments[1].Content=第+秒+Comment

如何以干净的方式实现这一点?我们只能想到两种似乎都会影响设计的方法:

  • 要么我们将BlogPost作为模型传递给局部视图,这样我们就可以定义如下的文本区域:@Html.TextAreaFor(x => x.Comments[i].Content)。但这意味着我们将用于注释的局部视图与父视图模型相耦合——您可以考虑在不同的上下文中使用相同的局部视图的场景,如果局部视图依赖于父视图模型,则这是不可能的。此外,i必须以某种方式传递到局部视图
  • 或者我们回到用字符串明确定义每个字段的名称:@Html.TextArea(ViewBag.Prefix + ".Content")

有什么方法可以告诉局部视图将某个前缀应用于所有字段名吗?

chiccodoro,

如果您创建类型为Comment的EditorFor模板,mvc将为您完美地处理所有这些。然而,只有在DB中已经存在行的情况下,这种方法才能很好地工作。SO的Exampel:

提交父级&儿童在剃须刀

如果您需要动态创建新行,那么您必须使用一些技巧来允许字段按需操作。我使用了steven sandersons网站上的一篇文章,该文章允许您在运行时添加收藏项目,并且仍然保留不引人注目的验证等。请参阅此SO问题和相关文章参考:

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

最新更新