ASP.NET Core MVC中如何绑定分部视图与局部视图的所有子模型
问题原因
直接向分部视图传递子模型实例时,ASP.NET MVC生成的输入控件name属性不会携带父模型的属性前缀,导致提交后模型绑定器无法将字段映射到CollegeModel的对应子属性上。比如StudentDetails分部里生成的Id字段name是Id,而模型绑定需要的是Students.Id才能匹配到CollegeModel.Students.Id。
解决方案
提供两种常用可行方案:
方案1:给分部视图传递前缀的ViewData
修改父视图调用分部的代码,手动指定字段前缀:
@if (Model.Students != null) { // 若为.NET Framework版MVC5及更早,替换为@Html.Partial,去掉await @await Html.PartialAsync("StudentDetails", Model.Students, new ViewDataDictionary(ViewData) { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = nameof(Model.Students) } }) } @if (Model.Teachers != null) { @await Html.PartialAsync("TeachersDetails", Model.Teachers, new ViewDataDictionary(ViewData) { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = nameof(Model.Teachers) } }) }
配置后分部视图中用@Html.EditorFor(x=>x.Id)这类强类型助手生成的控件name会自动带上Students./Teachers.前缀,匹配父模型的属性结构。
方案2:使用EditorTemplates(更推荐)
- 在项目
Views/Shared目录下新建EditorTemplates文件夹 - 在该文件夹下新建和子模型类名同名的cshtml文件,比如
Students.cshtml、Teachers.cshtml,把原分部视图的内容直接挪到对应文件中 - 父视图里直接调用编辑器模板即可,无需手动传前缀:
@if (Model.Students != null) { @Html.EditorFor(x=>x.Students) } @if (Model.Teachers != null) { @Html.EditorFor(x=>x.Teachers) }
编辑器模板会自动生成正确的name属性前缀,代码更简洁,出错概率更低。
补充校验点
- 分部视图/编辑器模板内一定要用强类型HTML助手生成输入控件,比如
@Html.TextBoxFor(x=>x.Name),不要手动写<input name="Name">,否则不会自动携带前缀 - 后台接收Action的参数必须是
CollegeModel类型,不要拆分写Teachers、Students等独立参数,否则绑定会失败
示例Action代码:
[HttpPost] public ActionResult SaveExportData(CollegeModel model) { // 此处可正常获取model.Students、model.Teachers的所有提交数据 // 后续业务逻辑 }
内容的提问来源于stack exchange,提问作者Sumit Bisht
相关产品推荐
相关产品推荐

