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

如何在System.Text.Json中为IEnumerable<T>使用自定义JsonConverter

问题描述

我使用自定义的System.Text.Json.JsonConverter来序列化/反序列化可表示为整数值的复杂枚举类型MyEnumType实例。当将转换器应用于单个属性时,JSON序列化符合预期,转换器功能正常:

[JsonConverter(typeof(MyEnumTypeConverter))]
public MyEnumType Member { get; set; }

但将同一转换器应用于集合属性时却失败(原因是转换器类型与属性类型不匹配):

[JsonConverter(typeof(MyEnumTypeConverter))]
public IEnumerable<MyEnumType> Members { get; set; }

我理解这种行为,但期望JSON序列化器能自动推断出应使用MyEnumType的自定义转换器来处理IEnumerable<MyEnumType>的元素。请问是否有办法配置JSON序列化,使其在处理集合元素时使用相同的JSON转换器?或者是否需要创建支持IEnumerable的自定义转换器版本?如果是后者,能否提供代码示例?

解决方案

方法1:全局注册转换器(推荐)

无需给集合属性单独标记转换器,直接在JsonSerializerOptions中注册MyEnumTypeConverter即可。序列化器会自动使用该转换器处理所有MyEnumType类型的对象,包括集合中的元素:

var options = new JsonSerializerOptions
{
    Converters = { new MyEnumTypeConverter() }
};

// 序列化示例
var json = JsonSerializer.Serialize(yourObjectInstance, options);

// 反序列化示例
var targetObject = JsonSerializer.Deserialize<YourTargetType>(json, options);

采用这种方式后,所有MyEnumType实例(无论是单个属性还是集合元素)都会通过你的自定义转换器完成序列化/反序列化,不需要修改集合属性的特性标记。

方法2:创建集合专用转换器(仅当无法全局注册时使用)

如果必须通过属性标记指定转换器,需要编写一个针对IEnumerable<MyEnumType>的专用转换器,内部复用已有的MyEnumTypeConverter处理单个元素:

public class MyEnumTypeCollectionConverter : JsonConverter<IEnumerable<MyEnumType>>
{
    private readonly MyEnumTypeConverter _elementConverter = new MyEnumTypeConverter();

    public override IEnumerable<MyEnumType> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType != JsonTokenType.StartArray)
        {
            throw new JsonException("JSON token is not an array.");
        }

        var elements = new List<MyEnumType>();
        while (reader.Read())
        {
            if (reader.TokenType == JsonTokenType.EndArray)
                break;

            // 复用单个元素转换器反序列化
            var element = _elementConverter.Read(ref reader, typeof(MyEnumType), options);
            elements.Add(element);
        }

        return elements;
    }

    public override void Write(Utf8JsonWriter writer, IEnumerable<MyEnumType> value, JsonSerializerOptions options)
    {
        writer.WriteStartArray();
        foreach (var item in value)
        {
            // 复用单个元素转换器序列化
            _elementConverter.Write(writer, item, options);
        }
        writer.WriteEndArray();
    }
}

随后将该转换器标记在集合属性上即可:

[JsonConverter(typeof(MyEnumTypeCollectionConverter))]
public IEnumerable<MyEnumType> Members { get; set; }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:52:41