Asp.Net Core Razor:如何将分部视图模型传递至PageModel?
问题根源
你当前的核心问题有两个:
- 分部视图用
foreach生成的复选框没有索引化的命名结构,ASP.NET Core的模型绑定无法识别列表项,导致回发后Files集合为空; - 用
asp-route-data传递复杂对象的方式不可行,路由仅支持传递简单类型值,无法携带完整的模型数据。
解决方案
1. 修复分部视图的表单元素命名
将foreach循环改为for循环(要求Files是实现IList的集合,比如List<FileObject>),这样生成的表单元素会带有Files[0].IsSelected这类索引化的name属性,模型绑定才能正确解析列表项。同时必须添加隐藏域保存文件名,确保回发时能携带完整的FileObject数据。
修改后的分部视图代码:
@model FileContents <div class="form-group"> <table> <tbody> @for (int i = 0; i < Model.Files.Count; i++) { <tr> <td class="clsChkBox" data-item="@Model.Files[i].Name"> @Html.CheckBoxFor(model => model.Files[i].IsSelected) <!-- 隐藏域保存文件名,回发时确保Name属性不丢失 --> @Html.HiddenFor(model => model.Files[i].Name) </td> <td>@Model.Files[i].Name</td> </tr> } </tbody> </table> </div>
2. 正确包裹表单
确保所有表单元素都在<form>标签内,两种可选方式:
方式一:在分部视图内添加表单
@model FileContents <form method="post" asp-page-handler="ExportData"> <div class="form-group"> <table> <tbody> @for (int i = 0; i < Model.Files.Count; i++) { <tr> <td class="clsChkBox" data-item="@Model.Files[i].Name"> @Html.CheckBoxFor(model => model.Files[i].IsSelected) @Html.HiddenFor(model => model.Files[i].Name) </td> <td>@Model.Files[i].Name</td> </tr> } </tbody> </table> </div> <button type="submit">确认导出</button> </form>
方式二:在主页面用表单包裹分部视图容器
<form method="post" asp-page-handler="ExportData"> <div class="dvExport" id="exportPartial"></div> <button type="submit">确认导出</button> </form>
3. 确保模型类符合绑定要求
FileContents和FileObject必须具备公共无参构造函数,且属性为公共可读写:
public class FileContents { public FileContents() { Files = new List<FileObject>(); } public List<FileObject> Files { get; set; } } public class FileObject { public FileObject() { } // 必须有无参构造函数 public FileObject(string name, bool isSelected) { Name = name; IsSelected = isSelected; } public string Name { get; set; } public bool IsSelected { get; set; } }
4. 修复Post方法
两种接收模型的方式任选其一:
方式一:直接用参数接收
public IActionResult OnPostExportData(FileContents data) { // 此时data.Files可正确获取用户选择的数据 Console.WriteLine(data.Files.Count); return Page(); }
方式二:用[BindProperty]绑定到PageModel属性
[BindProperty] public FileContents ExportData { get; set; } public IActionResult OnPostExportData() { Console.WriteLine(ExportData.Files.Count); return Page(); }
5. AJAX提交的正确写法
如果用AJAX提交,不要序列化页面初始的@Model.ExportData,要序列化表单内的所有用户修改后的输入元素,同时携带防伪造令牌:
function submitExport() { $.ajax({ url: '/Index?handler=ExportData', type: 'POST', data: $('#exportForm').serialize(), headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() }, success: function(result) { // 处理成功逻辑 } }); }
内容的提问来源于stack exchange,提问作者tval
相关产品推荐
相关产品推荐

