Heim >Backend-Entwicklung >C++ >Warum löst JSON.Net bei Verwendung der JsonConvert-Annotation eine StackOverflowException aus und wie kann dies behoben werden?

Warum löst JSON.Net bei Verwendung der JsonConvert-Annotation eine StackOverflowException aus und wie kann dies behoben werden?

Patricia Arquette
Patricia ArquetteOriginal
2025-01-20 15:41:09227Durchsuche

Why Does JSON.Net Throw a StackOverflowException When Using the JsonConvert Annotation, and How Can It Be Fixed?

Auflösen der StackOverflowException von JSON.Net bei Verwendung des JsonConvert-Attributs

Das Serialisieren abgeflachter Klassen mithilfe des [JsonConvert]-Attributs kann zu einem StackOverflowException in JSON.Net führen. Dieses Problem ist, anders als bei der direkten Verwendung von SerializeObject, auf rekursive Aufrufe zurückzuführen.

Die Lösung: Rekursive Serialisierung vermeiden

Das Problem entsteht durch das Zusammenspiel von benutzerdefinierten Konvertern und JsonConvert. Wenn ein benutzerdefinierter Konverter (z. B. [JsonConverter(typeof(FJson))]) angewendet wird, wird seine Methode WriteJson aufgerufen. Wenn diese Methode wiederum JsonConvert.SerializeObject aufruft (entweder direkt oder indirekt), wird eine rekursive Schleife erstellt, was zum Stapelüberlauf führt.

Codeänderung für WriteJson

Um diese Rekursion zu verhindern, muss die Methode WriteJson neu geschrieben werden, um jede Eigenschaft einzeln zu serialisieren und den rekursiven Aufruf von JsonConvert.SerializeObject zu vermeiden. Hier ist eine überarbeitete Implementierung:

<code class="language-csharp">public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    if (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;
        writer.WritePropertyName(propertyName);

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

        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>

Erklärung:

Diese überarbeitete WriteJson Methode durchläuft jede Eigenschaft des Objekts. Es prüft auf ignorierte Eigenschaften und ShouldSerialize-Methoden, bevor der Wert jeder Eigenschaft direkt mit dem Serialisierer serialisiert wird. Dadurch entfällt der rekursive Aufruf und die Auflösung von StackOverflowException.

Fazit:

Durch die direkte Serialisierung einzelner Eigenschaften innerhalb der WriteJson-Methode des benutzerdefinierten Konverters unterbrechen wir den rekursiven Zyklus, verhindern das StackOverflowException und stellen eine zuverlässige Serialisierung abgeflachter Klassen sicher. Dieser Ansatz bietet eine robuste Lösung für die Verwaltung komplexer Objektstrukturen innerhalb von JSON.Net.

Das obige ist der detaillierte Inhalt vonWarum löst JSON.Net bei Verwendung der JsonConvert-Annotation eine StackOverflowException aus und wie kann dies behoben werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn