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

如何用System.Text.Json自定义转换器兼容解析单对象和列表JSON

实现方案

步骤1:编写通用自定义JsonConverter

继承JsonConverter<IList<T>>实现自动适配单对象/数组的解析逻辑:

using System.Text.Json;
using System.Text.Json.Serialization;

public class SingleOrArrayConverter<T> : JsonConverter<IList<T>>
{
    public override IList<T>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        switch (reader.TokenType)
        {
            // 传入为数组格式,正常解析
            case JsonTokenType.StartArray:
                return JsonSerializer.Deserialize<List<T>>(ref reader, options);
            // 传入为单个对象,解析后包装为列表返回
            case JsonTokenType.StartObject:
                var singleItem = JsonSerializer.Deserialize<T>(ref reader, options);
                return singleItem == null ? new List<T>() : new List<T> { singleItem };
            // 空值处理,可按需调整为返回null
            case JsonTokenType.Null:
                return new List<T>();
            default:
                throw new JsonException($"不支持的令牌类型:{reader.TokenType}");
        }
    }

    public override void Write(Utf8JsonWriter writer, IList<T> value, JsonSerializerOptions options)
    {
        // 序列化默认输出数组格式,若需要适配单对象输出可自行修改此处逻辑
        JsonSerializer.Serialize(writer, value, options);
    }
}

步骤2:使用转换器

在反序列化时注册转换器即可同时兼容两种响应格式:

// 配置序列化参数
var jsonOptions = new JsonSerializerOptions();
jsonOptions.Converters.Add(new SingleOrArrayConverter<ExampleResponse>());

// 执行反序列化,无需判断响应格式
var response = JsonSerializer.Deserialize<IList<ExampleResponse>>(content, jsonOptions);

如果需要全局适配,也可以直接给对应实体类的集合属性添加特性:[JsonConverter(typeof(SingleOrArrayConverter<ExampleResponse>))]。

验证效果

  • 当返回示例1的数组格式时,response为对应长度的IList<ExampleResponse>集合
  • 当返回示例2的单对象格式时,response为长度为1的IList<ExampleResponse>集合,元素为返回的单个对象

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 19:36:04