Web API向Blazor WASM传递带子对象集合的对象时集合为空
问题原因
你的PlayerSingers成员是公共字段,不是公共属性。Blazor Hosted模板默认使用System.Text.Json完成JSON序列化/反序列化,该序列化器默认仅处理对象的公共属性,不会处理公共字段。因此服务端返回结果时根本没有把这个集合写入JSON响应,客户端反序列化时自然无法给这个成员赋值,始终保持你定义的初始空列表状态。
修复方法
推荐方案(无需额外序列化配置,符合C#编码规范)
将Player类中的PlayerSingers从公共字段改为带get/set访问器的公共属性即可,修改后的类代码如下:
public class Player { // PartyId public int Id { get; set; } public DateTime CreatedDate { get; set; } public string? HostSingerId { get; set; } [Display(Name = "Join Code")] public int JoinCode { get; set; } // Party Name public string? Name { get; set; } // 原写法是公共字段,改为属性 public IEnumerable<PlayerSinger> PlayerSingers { get; set; } = new List<PlayerSinger>(); }
修改后无需调整接口和客户端请求代码,重启应用即可正常传递嵌套集合。你可以先直接在浏览器访问对应GET接口地址,确认返回的JSON内容中包含playerSingers字段,即可验证序列化正常。
备选方案(仅当必须保留公共字段写法时使用)
如果你出于特殊原因必须将PlayerSingers保留为公共字段,需要同时修改服务端和客户端的序列化配置,开启字段序列化支持:
- 服务端
Program.cs中配置JSON选项支持字段序列化
builder.Services.AddControllersWithViews() .AddJsonOptions(opts => { opts.JsonSerializerOptions.IncludeFields = true; });
- 客户端发起请求时传入带字段序列化支持的配置
public async Task<Player> Get(int id) { var jsonOpts = new JsonSerializerOptions { IncludeFields = true }; var x = await _client.GetFromJsonAsync<Player>($"api/player/get/{id}", jsonOpts); return x; }
你之前检索的参数绑定、嵌套对象返回相关资料没有命中问题,是因为那些资料对应的问题场景多为循环引用、导航属性未加载、属性访问级别不对,和你遇到的字段/属性序列化规则差异不是同一类问题,后续检索可以使用「System.Text.Json 字段不序列化」作为关键词。
内容的提问来源于stack exchange,提问作者niico
相关产品推荐
相关产品推荐

