使用 System.Text.Json 序列化期间出现 StackOverflowException

问题描述 投票:0回答:1

我不明白为什么下面的代码在

StackOverflowException
期间抛出
Write
。我希望能够使用类型鉴别器来帮助我序列化/反序列化对象,同时不丢失具体的实现细节。我该如何解决这个问题?

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

public abstract class ClassC
{
    public string PropertyC { get; set; }
    public string TypeDiscriminator => this.GetType().FullName;
}

public class ClassB : ClassC
{
    public string PropertyB { get; set; }
}

public class ClassA : ClassB
{
    public string PropertyA { get; set; }
}

public class PolymorphicJsonConverter<TBase> : JsonConverter<TBase> where TBase : ClassC
{
    public override bool CanConvert(Type typeToConvert) => typeof(TBase).IsAssignableFrom(typeToConvert);

    public override TBase Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using (var jsonDoc = JsonDocument.ParseValue(ref reader))
        {
            var root = jsonDoc.RootElement;
            var typeDiscriminator = root.GetProperty("TypeDiscriminator").GetString();

            var type = Type.GetType(typeDiscriminator);
            if (type == null)
            {
                throw new JsonException($"Type {typeDiscriminator} could not be found.");
            }

            return (TBase)JsonSerializer.Deserialize(root.GetRawText(), type, options);
        }
    }

    public override void Write(Utf8JsonWriter writer, TBase value, JsonSerializerOptions options)
    {
        JsonSerializer.Serialize(writer, value, value.GetType(), options);
    }
}

public class Program
{
    public static void Main()
    {
        var options = new JsonSerializerOptions
        {
            Converters = { new PolymorphicJsonConverter<ClassC>() },
            WriteIndented = true
        };

        ClassA classA = new ClassA { PropertyA = "ValueA", PropertyB = "ValueB", PropertyC = "ValueC" };

        string json = JsonSerializer.Serialize<ClassC>(classA, options);
        ClassC deserialized = JsonSerializer.Deserialize<ClassC>(json, options);

        Console.WriteLine(json);
        Console.WriteLine(deserialized is ClassA); // Should output 'True'
    }
}
c# .net serialization polymorphism system.text.json
1个回答
0
投票

在您的

Write
方法中,您再次调用您的
Write
方法 - 您有一个循环 - 一段时间后,您的应用程序内存不足。在
Write
方法中打个断点看看。

您应该在

writer
方法中使用
Write
。这是文档中的基本转换器示例

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

namespace SystemTextJsonSamples
{
    public class DateTimeOffsetJsonConverter : JsonConverter<DateTimeOffset>
    {
        public override DateTimeOffset Read(
            ref Utf8JsonReader reader,
            Type typeToConvert,
            JsonSerializerOptions options) =>
                DateTimeOffset.ParseExact(reader.GetString()!,
                    "MM/dd/yyyy", CultureInfo.InvariantCulture);

        public override void Write(
            Utf8JsonWriter writer,
            DateTimeOffset dateTimeValue,
            JsonSerializerOptions options) =>
                writer.WriteStringValue(dateTimeValue.ToString(
                    "MM/dd/yyyy", CultureInfo.InvariantCulture));
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.