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

C# .NET:使用System.Text.Json将JSON数组反序列化为IList<Interface>

解决System.Text.Json反序列化接口集合(如IList)的问题

System.Text.Json默认不支持直接将JSON数组反序列化为IList<TInterface>这类接口集合类型,要替代Newtonsoft.Json中JsonArrayAttribute+CustomCreationConverter<T>的组合,核心是自定义泛型转换器,明确指定集合和元素的具体实现类。

具体实现步骤:

1. 定义接口与具体实现类

假设我们有如下接口和具体类:

public interface IFoo
{
    string Name { get; set; }
}

public class ConcreteFoo : IFoo
{
    public string Name { get; set; }
}

2. 自定义接口集合转换器

编写一个泛型转换器,实现JsonConverter<IList<TInterface>>,在反序列化时将JSON数组转为具体集合类型,再转换为接口集合:

public class InterfaceListConverter<TInterface, TConcrete> : JsonConverter<IList<TInterface>> 
    where TConcrete : class, TInterface
{
    public override IList<TInterface> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 先反序列化为具体元素的集合
        var concreteItems = JsonSerializer.Deserialize<List<TConcrete>>(ref reader, options);
        // 转换为接口集合返回,空值则返回空列表
        return concreteItems?.Cast<TInterface>().ToList() ?? new List<TInterface>();
    }

    public override void Write(Utf8JsonWriter writer, IList<TInterface> value, JsonSerializerOptions options)
    {
        // 序列化时将接口集合转为具体类型集合再处理
        JsonSerializer.Serialize(writer, value.Cast<TConcrete>(), options);
    }
}

3. 使用转换器的两种方式

方式一:反序列化时手动传入配置
var jsonArray = @"[{""Name"":""FirstFoo""},{""Name"":""SecondFoo""}]";

var options = new JsonSerializerOptions();
// 添加自定义转换器
options.Converters.Add(new InterfaceListConverter<IFoo, ConcreteFoo>());

// 直接反序列化为IList<IFoo>
var interfaceList = JsonSerializer.Deserialize<IList<IFoo>>(jsonArray, options);
方式二:给模型属性添加特性标记

如果接口集合是某个模型的属性,可以直接用JsonConverterAttribute指定转换器:

public class MyBusinessModel
{
    [JsonConverter(typeof(InterfaceListConverter<IFoo, ConcreteFoo>))]
    public IList<IFoo> FooItems { get; set; }
}

// 反序列化模型
var model = JsonSerializer.Deserialize<MyBusinessModel>(jsonArray);

额外说明

  • 如果需要支持其他集合接口(如ICollection<TInterface>、IEnumerable<TInterface>),可以修改转换器的泛型参数,实现对应的JsonConverter接口即可。
  • 若具体实现类没有无参构造函数,需要在JsonSerializerOptions中配置允许使用非公共构造函数,或者确保类有可访问的无参构造。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 15:35:58