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
相关产品推荐
相关产品推荐

