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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:56:35