You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Asp.Net Core Razor:如何将分部视图模型传递至PageModel?

问题根源

你当前的核心问题有两个:

  1. 分部视图用foreach生成的复选框没有索引化的命名结构,ASP.NET Core的模型绑定无法识别列表项,导致回发后Files集合为空;
  2. 用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 00:10:50