.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
相关产品推荐
相关产品推荐

