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

Newtonsoft JSON反序列化:空列表以{}代替[]引发异常的解决方案

解决Newtonsoft.Json兼容空列表为{}的反序列化问题

问题背景

对接第三方API时遇到JSON格式不一致:列表有值时返回数组[],空列表时却返回空对象{},导致反序列化IList<T>类型时抛出JsonSerializationException。

现成配置说明

Newtonsoft.Json没有直接的内置配置开关来兼容这种情况,最优雅的解决方式是自定义JSON转换器,在反序列化阶段自动处理{}为空列表的场景。

实现方案:自定义JsonConverter

1. 编写泛型转换器

创建一个通用转换器,处理IList<T>类型的反序列化,遇到空对象时返回空列表:

public class EmptyObjectToListConverter<T> : JsonConverter<IList<T>>
{
    public override IList<T> ReadJson(JsonReader reader, Type objectType, IList<T> existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        return reader.TokenType switch
        {
            JsonToken.StartArray => serializer.Deserialize<List<T>>(reader),
            JsonToken.StartObject => new List<T>(),
            JsonToken.Null => null,
            _ => throw new JsonSerializationException($"无法处理的Token类型:{reader.TokenType}")
        };
    }

    public override void WriteJson(JsonWriter writer, IList<T> value, JsonSerializer serializer)
    {
        // 序列化时保持正常数组格式
        serializer.Serialize(writer, value);
    }
}

2. 应用转换器到目标属性

修改你的GenericNamedResponseObject类,在Info属性上添加转换器标记:

[Serializable]
public class GenericNamedResponseObject
{
    [JsonProperty("code")]
    public int? Code { get; set; }

    [JsonProperty("msg")]
    public string ErrorMessage { get; set; }
    
    private IList<GenericResponseLineItem> _info;

    [JsonProperty("info")]
    [JsonConverter(typeof(EmptyObjectToListConverter<GenericResponseLineItem>))]
    public IList<GenericResponseLineItem> Info
    {
        get => _info ?? (_info = new List<GenericResponseLineItem>());
        set => _info = value;
    }
}

3. (可选)全局注册转换器

如果多个地方都需要处理这种兼容场景,可以将转换器全局注册到JsonSerializerSettings,避免重复标记属性:

var jsonSettings = new JsonSerializerSettings();
jsonSettings.Converters.Add(new EmptyObjectToListConverter<GenericResponseLineItem>());

// 使用全局配置反序列化
var response = JsonConvert.DeserializeObject<GenericNamedResponseObject>(jsonString, jsonSettings);

方案优势

  • 无需冗余的try/catch重试逻辑,代码更简洁
  • 精准控制特定类型的反序列化规则,不影响其他属性
  • 序列化时保持标准数组格式,不会破坏输出规范

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 16:44:55