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

.NET 7中实现IEnumerable的TestSuite类JSON反序列化失败求助

解决方案:处理TestSuite的System.Text.Json反序列化问题

问题根源是System.Text.Json会优先将实现IEnumerable<T>的类型识别为集合类型,而默认集合反序列化逻辑无法直接实例化自定义TestSuite类并填充数据——尤其是当它同时实现ITest接口时,序列化/反序列化的逻辑冲突会导致报错。

方案一:调整TestSuite结构(推荐,无需自定义转换器)

将集合逻辑封装为内部属性,通过显式实现IEnumerable<ITest>保留遍历能力,让System.Text.Json将其视为普通对象处理:

public interface ITest { /* 你的接口定义 */ }

public class TestCase : ITest { /* 实现内容 */ }

public class TestSuite : ITest, IEnumerable<ITest>
{
    // 用普通列表属性存储子测试项
    public List<ITest> Tests { get; set; } = new();

    // 显式实现IEnumerable接口,不干扰Json序列化逻辑
    IEnumerator<ITest> IEnumerable<ITest>.GetEnumerator() => Tests.GetEnumerator();
    IEnumerator IEnumerable.GetEnumerator() => Tests.GetEnumerator();

    // 其他ITest接口的实现属性/方法
}

反序列化时,在JsonSerializerOptions中配置多态处理(针对ITest):

var options = new JsonSerializerOptions
{
    TypeInfoResolver = new DefaultJsonTypeInfoResolver
    {
        Modifiers =
        {
            typeInfo =>
            {
                if (typeInfo.Type == typeof(ITest))
                {
                    typeInfo.PolymorphismOptions = new JsonPolymorphismOptions
                    {
                        TypeDiscriminatorPropertyName = "$type",
                        DerivedTypes =
                        {
                            new JsonDerivedType(typeof(TestCase), nameof(TestCase)),
                            new JsonDerivedType(typeof(TestSuite), nameof(TestSuite))
                        }
                    };
                }
            }
        }
    }
};

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

方案二:实现正确的自定义JsonConverter

如果不想修改类结构,可以针对TestSuite编写转换器,手动处理集合元素和其他属性的序列化/反序列化:

public class TestSuiteConverter : JsonConverter<TestSuite>
{
    public override TestSuite Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using var doc = JsonDocument.ParseValue(ref reader);
        var root = doc.RootElement;
        var testSuite = new TestSuite();

        // 1. 反序列化TestSuite自身的非集合属性(如果有)
        // if (root.TryGetProperty("SuiteName", out var nameProp))
        //     testSuite.SuiteName = nameProp.GetString();

        // 2. 反序列化集合元素(适配数组格式的序列化结果)
        foreach (var element in root.EnumerateArray())
        {
            var test = JsonSerializer.Deserialize<ITest>(element, options);
            testSuite.Add(test); // 假设TestSuite有Add方法添加子测试项
        }

        return testSuite;
    }

    public override void Write(Utf8JsonWriter writer, TestSuite value, JsonSerializerOptions options)
    {
        // 按数组格式序列化TestSuite的集合元素
        JsonSerializer.Serialize(writer, value as IEnumerable<ITest>, options);
    }
}

使用时将转换器添加到配置中:

var options = new JsonSerializerOptions();
options.Converters.Add(new TestSuiteConverter());
// 同时配置ITest的多态映射(同方案一)

var testSuite = JsonSerializer.Deserialize<TestSuite>(json, options);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 07:30:59