Rumah > pembangunan bahagian belakang > C++ > Mengapakah menggunakan anotasi `[JsonConvert()]` dengan JsonConverters tersuai kadangkala menghasilkan StackOverflowException, dan bagaimana saya boleh menghalangnya?

Mengapakah menggunakan anotasi `[JsonConvert()]` dengan JsonConverters tersuai kadangkala menghasilkan StackOverflowException, dan bagaimana saya boleh menghalangnya?

Patricia Arquette
Lepaskan: 2025-01-20 15:25:15
asal
704 orang telah melayarinya

Why does using the `[JsonConvert()]` annotation with custom JsonConverters sometimes result in a StackOverflowException, and how can I prevent it?

JSON.NET StackOverflowException dan [JsonConvert] Atribut

Menggunakan atribut [JsonConvert] pada tersuai JsonConverter boleh membawa kepada StackOverflowException semasa penyirian, terutamanya dengan objek kompleks. Ini selalunya disebabkan oleh rekursi tak terhingga dalam proses siri dalaman JSON.NET. Walaupun menggunakan terus JsonConvert.SerializeObject() dengan penukar tersuai anda ialah penyelesaian yang disyorkan, bahagian ini meneroka pendekatan alternatif apabila atribut itu diperlukan.

1. Memperhalusi Kaedah WriteJson

Inti masalah selalunya terletak pada kaedah WriteJson penukar tersuai anda. Pengendalian kes tepi yang tidak mencukupi boleh mencetuskan gelung tak terhingga. Kaedah WriteJson yang dipertingkatkan berikut menangani beberapa senario biasa:

<code class="language-csharp">public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
    if (ReferenceEquals(value, null)) {
        writer.WriteNull();
        return;
    }

    var contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(value.GetType());

    writer.WriteStartObject();

    foreach (var property in contract.Properties) {
        if (property.Ignored) continue;
        if (!ShouldSerialize(property, value)) continue;

        var propertyName = property.PropertyName;
        var propertyValue = property.ValueProvider.GetValue(value);

        writer.WritePropertyName(propertyName);
        if (property.Converter != null && property.Converter.CanWrite) {
            property.Converter.WriteJson(writer, propertyValue, serializer);
        } else {
            serializer.Serialize(writer, propertyValue);
        }
    }

    writer.WriteEndObject();
}

private static bool ShouldSerialize(JsonProperty property, object instance) {
    return property.ShouldSerialize == null || property.ShouldSerialize(instance);
}</code>
Salin selepas log masuk

Versi ini secara eksplisit mengendalikan nilai nol dan menggunakan penyelesai kontrak untuk melelang melalui sifat, melangkau sifat diabaikan dan yang ShouldSerialize mengembalikan palsu. Ia juga mewakilkan siri dengan betul kepada penukar harta jika ada dan boleh menulis, jika tidak, menggunakan siri terus.

2. Panggilan Rekursif dengan Had Saiz Tindanan

Sebagai alternatif, anda boleh menambah semakan kedalaman tindanan dalam kaedah WriteJson anda untuk mengelakkan pengulangan lari:

<code class="language-csharp">public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
    const int MaxStackSize = 65536; // Adjust as needed

    if (writer.CurrentDepth > MaxStackSize) {
        throw new JsonSerializationException("Stack overflow detected during serialization.");
    }

    // Your custom serialization logic here...
}</code>
Salin selepas log masuk

Pendekatan ini memberikan pengecualian deskriptif jika kedalaman rekursi melebihi had yang telah ditetapkan, menghalang StackOverflowException. Laraskan MaxStackSize berdasarkan kerumitan objek anda.

Kesimpulan

Walaupun atribut [JsonConvert] menawarkan kemudahan, menggunakannya dengan penukar tersuai memerlukan pertimbangan yang teliti. Dengan meningkatkan kaedah WriteJson anda untuk mengendalikan kes tepi dan/atau menggabungkan semakan saiz tindanan, anda boleh mengurangkan risiko StackOverflowException dengan berkesan semasa penyirian. Ingat bahawa panggilan JsonConvert.SerializeObject() secara manual kekal sebagai pendekatan yang paling selamat dan boleh dipercayai.

Atas ialah kandungan terperinci Mengapakah menggunakan anotasi `[JsonConvert()]` dengan JsonConverters tersuai kadangkala menghasilkan StackOverflowException, dan bagaimana saya boleh menghalangnya?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan