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

ASP.NET Core 6.0多层嵌套列表绑定失败问题求助

问题分析与解决方案

你的核心问题在于表单字段的命名未遵循ASP.NET Core嵌套集合的模型绑定规则,导致控制器无法识别Window下的Additions和Services集合数据。以下是具体原因和修复步骤:

为什么嵌套集合无法绑定?

ASP.NET Core模型绑定对于嵌套集合,要求表单字段名必须包含完整的层级索引路径,格式为:
ParentCollection[ParentIndex].ChildCollection[ChildIndex].Property

而你当前的Addition部分视图直接使用Model[i].Name,生成的字段名是[i].Name,缺少上层Windows[N].的前缀,绑定系统无法将这些值关联到对应的Window实例的Additions集合中。


修复步骤

1. 修改Window部分视图,生成正确的嵌套字段名

将_NewWindow.cshtml的模型改为PriceOffer,在循环渲染Window的同时,嵌套渲染其Additions和Services,确保字段名包含完整层级:

@using PriceOfferApp.Models.Settings;
@model PriceOffer
@{
    IEnumerable<Color> colors = ViewData["Colors"] as IEnumerable<Color>;
    IEnumerable<WindowSystem> systems = ViewData["Systems"] as IEnumerable<WindowSystem>;
    IEnumerable<Glass> glasses = ViewData["Glasses"] as IEnumerable<Glass>;
}

@for (int windowIdx = 0; windowIdx < Model.Windows.Count(); windowIdx++)
{
    <div class="window-item" data-window-index="@windowIdx">
        <!-- Window基础字段 -->
        <input asp-for="@Model.Windows[windowIdx].Width" />
        <input asp-for="@Model.Windows[windowIdx].Height" />
        <!-- 其他Window字段(ColorID、GlassID等) -->

        <!-- 渲染Additions集合 -->
        <div class="additions-group">
            @if (Model.Windows[windowIdx].Additions != null)
            {
                for (int addIdx = 0; addIdx < Model.Windows[windowIdx].Additions.Count(); addIdx++)
                {
                    <input asp-for="@Model.Windows[windowIdx].Additions[addIdx].Name" />
                    <input asp-for="@Model.Windows[windowIdx].Additions[addIdx].Price" />
                }
            }
            <button type="button" class="btn-add-addition">添加附加项</button>
        </div>

        <!-- 渲染Services集合(逻辑同Additions) -->
        <div class="services-group">
            @if (Model.Windows[windowIdx].Services != null)
            {
                for (int serviceIdx = 0; serviceIdx < Model.Windows[windowIdx].Services.Count(); serviceIdx++)
                {
                    <input asp-for="@Model.Windows[windowIdx].Services[serviceIdx].Name" />
                    <!-- 其他Service字段 -->
                }
            }
            <button type="button" class="btn-add-service">添加服务</button>
        </div>
    </div>
}

2. 修正动态添加元素的JavaScript逻辑

动态添加Addition或Service时,必须生成符合规则的字段名,确保包含对应的Window索引和子集合索引:

// 动态添加Addition示例
$(document).on('click', '.btn-add-addition', function() {
    const windowItem = $(this).closest('.window-item');
    const windowIdx = windowItem.data('window-index');
    const additionsGroup = windowItem.find('.additions-group');
    
    // 计算当前Addition的索引(每个Addition对应2个input,所以除以2)
    const addIdx = additionsGroup.find('input[name^="Windows[' + windowIdx + '].Additions"]').length / 2;

    // 创建符合绑定规则的输入框
    const nameInput = $('<input>').attr({
        type: 'text',
        name: `Windows[${windowIdx}].Additions[${addIdx}].Name`,
        placeholder: '附加项名称'
    });
    const priceInput = $('<input>').attr({
        type: 'number',
        name: `Windows[${windowIdx}].Additions[${addIdx}].Price`,
        placeholder: '价格'
    });

    additionsGroup.append(nameInput).append(priceInput);
});

// 动态添加Service的逻辑与Addition完全一致,只需替换字段名前缀为Windows[${windowIdx}].Services[${serviceIdx}]

3. 确保模型集合初始化

在Window类的构造函数中初始化嵌套集合,避免绑定时空引用:

public class Window
{
    [Key]
    public int Id { get; set; }

    [ForeignKey("PriceOfferId")]
    public int PriceOfferId { get; set; }

    public PriceOffer PriceOffer { get; set; }

    // 初始化集合,避免绑定为null
    public ICollection<Addition>? Additions { get; set; } = new List<Addition>();
    public ICollection<Service>? Services { get; set; } = new List<Service>();
}

验证绑定效果

修改完成后,提交表单时,浏览器会生成如下格式的字段名:

Windows[0].Width
Windows[0].Additions[0].Name
Windows[0].Additions[0].Price
Windows[1].Services[0].Name
...

ASP.NET Core模型绑定系统会自动识别这些字段,将数据正确映射到PriceOffer的嵌套集合中。

内容的提问来源于stack exchange,提问作者Patrik Spišák

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 05:37:09