当使用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")
。
有没有办法告诉部分视图将某个前缀应用于所有字段名称?