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

Blazor 8 SSR:含List的复杂对象模型绑定异常问题

解决Blazor EditForm复杂对象绑定后formData为null的问题

核心问题分析

你的代码里导致formData提交时为null的主要原因是使用foreach遍历集合生成表单控件,Blazor无法为foreach生成的控件创建带索引的表单字段名称,从而无法正确绑定到List<DiceTypeAmmount>集合。此外,模型类的构造逻辑和[SupplyParameterFromForm]的使用也需要调整。

修复步骤

1. 改用for循环遍历集合,生成带索引的绑定

将foreach替换为for循环,通过索引访问列表项,让Blazor生成符合绑定要求的字段名称:

@using DiceMaster.Lib.Dices
@using System.ComponentModel
<EditForm Enhance Model="@formData" OnValidSubmit="@RollDices" FormName="DiceRoller">
    @for (int i = 0; i < formData.Amounts.Count; i++)
    {
        var index = i;
        <InputSelect @bind-Value="formData.Amounts[index].DiceTypeId">
            @foreach (DiceType ty in diceTypeGetter.GetDiceTypes())
            {
                <option value="@ty.TypeId">@ty.Name</option>
            }
        </InputSelect>
        <InputNumber @bind-Value="formData.Amounts[index].DiceCount" min="1" max="1000000"></InputNumber>
    }

    <button type="submit">Roll</button>
</EditForm>

2. 确保模型类有无参构造函数

表单绑定需要框架能实例化模型对象,调整模型类添加无参构造并初始化集合:

public class RoleDiceFormInfo
{
    public List<DiceTypeAmmount> Amounts { get; set; } = new List<DiceTypeAmmount>();

    public RoleDiceFormInfo() {}
}

public class DiceTypeAmmount
{
    public Guid DiceTypeId { get; set; }
    public int DiceCount { get; set; }

    public DiceTypeAmmount() {}
}

3. 调整[SupplyParameterFromForm]的初始化逻辑

提前初始化模型对象,仅当集合为空时添加默认数据,避免覆盖表单提交的内容:

@code {
    [SupplyParameterFromForm]
    public RoleDiceFormInfo formData { get; set; } = new RoleDiceFormInfo();

    private DiceTypeGetter diceTypeGetter { get; set; } = new DiceTypeGetter();
    private List<DiceRollResult> rollResults { get; set; } = new List<DiceRollResult>();

    protected override void OnInitialized()
    {
        if (!formData.Amounts.Any())
        {
            var d6TypeId = diceTypeGetter.GetDiceTypes().First(d=>d.Name == "D6").TypeId;
            var d3TypeId = diceTypeGetter.GetDiceTypes().First(d=>d.Name == "D3").TypeId;
            
            formData.Amounts.Add(new DiceTypeAmmount { DiceCount = 1, DiceTypeId = d6TypeId });
            formData.Amounts.Add(new DiceTypeAmmount { DiceCount = 1, DiceTypeId = d3TypeId });
        }
    }

    private void RollDices()
    {
        DiceRoller roller = new DiceRoller();
        DiceRollRequest request = new DiceRollRequest();
        request.DiceAmmounts = new List<DiceTypeAmmount>(formData.Amounts);
        rollResults = roller.RollDices(request);
    }
}

关键原理说明

Blazor表单绑定依赖控件的name属性匹配模型字段,绑定集合时必须生成Amounts[0].DiceTypeId这类带索引的字段名,for循环能实现这一点,而foreach无法做到。同时,模型类必须提供无参构造,确保框架能在提交时实例化并填充数据。

内容的提问来源于stack exchange,提问作者Maera90

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 12:50:07