JSON反序列化为Cart对象时Lines集合为空问题求助
问题解决:JSON反序列化Cart对象后Lines集合为空
问题重现
反序列化JSON字符串{"Lines":[{"Id":9,"Count":1}]}到Cart对象时,c.Lines.Count()始终返回0,核心代码如下:
string str = this.HttpContext.Session.GetString("cart"); // {"Lines":[{"Id":9,"Count":1}]} Cart c = JsonSerializer.Deserialize<Cart>(str);
Cart与CartLine类定义:
[Serializable] public sealed class Cart { private readonly ICollection<CartLine> _lines = new Collection<CartLine>(); public void Add(CartLine line) { _lines.Add(line); } public void Remove(int productId) { CartLine tmp = _lines.Single(cr => cr.Id == productId); _lines.Remove(tmp); } public IEnumerable<CartLine> Lines => _lines; } [Serializable] public sealed class CartLine { public int Id { get; set; } public int Count { get; set; } }
问题原因
System.Text.Json默认序列化规则限制:
- 仅处理带有公共setter的属性,或可被访问的字段
Cart类的Lines是只读表达式体属性(=> _lines),没有setter,序列化器无法将JSON数组数据赋值到该属性- 私有字段
_lines默认不会被序列化器识别和访问
解决方案
方案1:给Lines属性添加私有setter
修改Cart类的Lines属性,通过私有setter接收反序列化的数据:
[Serializable] public sealed class Cart { private readonly ICollection<CartLine> _lines = new Collection<CartLine>(); public IEnumerable<CartLine> Lines { get => _lines; private set { if (value != null) { foreach (var line in value) { _lines.Add(line); } } } } // 原有Add、Remove方法保持不变 public void Add(CartLine line) { _lines.Add(line); } public void Remove(int productId) { CartLine tmp = _lines.Single(cr => cr.Id == productId); _lines.Remove(tmp); } }
方案2:标记私有字段映射JSON键
使用[JsonPropertyName]特性让序列化器直接识别私有字段_lines,对应JSON中的"Lines"键(需引用System.Text.Json.Serialization命名空间):
using System.Text.Json.Serialization; [Serializable] public sealed class Cart { [JsonPropertyName("Lines")] private readonly ICollection<CartLine> _lines = new Collection<CartLine>(); public void Add(CartLine line) { _lines.Add(line); } public void Remove(int productId) { CartLine tmp = _lines.Single(cr => cr.Id == productId); _lines.Remove(tmp); } public IEnumerable<CartLine> Lines => _lines; }
验证
修改后重新执行反序列化代码,c.Lines.Count()将返回1,与JSON中的数据一致。
内容的提问来源于stack exchange,提问作者SteinTech
相关产品推荐
相关产品推荐

