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

C# System.Text.Json反序列化时如何将空对象识别为空数组

System.Text.Json 没有提供开箱即用的配置项直接实现空对象到空数组的自动映射,该场景必须通过自定义JSON转换器实现,以下是可直接运行的生效方案:

自定义转换器实现

首先实现通用的转换器逻辑,既可以支持单属性标注,也可以支持全局注册适配所有数组类型:

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

// 具体数组类型转换器
public class EmptyObjectToEmptyArrayConverter<T> : JsonConverter<T[]>
{
    public override T[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 检测到当前令牌是对象起始标记(即遇到{}结构)
        if (reader.TokenType == JsonTokenType.StartObject)
        {
            // 必须消费掉整个空对象令牌,否则会导致后续读取位置错位触发异常
            reader.Skip();
            return Array.Empty<T>();
        }
        // 正常数组结构走默认反序列化逻辑
        return JsonSerializer.Deserialize<T[]>(ref reader, options);
    }

    public override void Write(Utf8JsonWriter writer, T[] value, JsonSerializerOptions options)
    {
        // 序列化逻辑保持默认即可,无需特殊处理
        JsonSerializer.Serialize(writer, value, options);
    }
}

// 转换器工厂,用于全局注册时自动适配所有数组元素类型
public class EmptyObjectToEmptyArrayConverterFactory : JsonConverterFactory
{
    public override bool CanConvert(Type typeToConvert)
    {
        return typeToConvert.IsArray;
    }

    public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
    {
        Type elementType = typeToConvert.GetElementType()!;
        return (JsonConverter)Activator.CreateInstance(
            typeof(EmptyObjectToEmptyArrayConverter<>).MakeGenericType(elementType))!;
    }
}

使用方式

  • 单属性生效(不影响其他逻辑):直接给对应属性加转换器标注即可
public class Something
{
    [JsonPropertyName("items")]
    [JsonConverter(typeof(EmptyObjectToEmptyArrayConverter<Item>))]
    public Item[] Items { get; set; }
}

反序列化时直接用默认选项即可正常解析两种格式的JSON。

  • 全局生效(所有数组自动适配):将转换器工厂注册到JsonSerializerOptions中,反序列化时传入该配置实例
var serializeOptions = new JsonSerializerOptions();
serializeOptions.Converters.Add(new EmptyObjectToEmptyArrayConverterFactory());

// 反序列化传入配置
var result = JsonSerializer.Deserialize<Something>(responseJson, serializeOptions);

自定义转换器不生效的常见原因

  • 遇到空对象时没有调用reader.Skip()消费完整对象令牌,导致JSON读取位置错位,触发后续解析异常
  • 转换器泛型类型与属性实际类型不匹配,比如属性是Item[]但转换器适配的是List<Item>类型
  • 全局注册后反序列化时没有传入带转换器配置的JsonSerializerOptions实例,使用了无配置的默认序列化选项

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 14:30:43