JSON.NET StackOverflowException und das [JsonConvert]
Attribut
Das Anwenden des [JsonConvert]
-Attributs auf ein benutzerdefiniertes JsonConverter
kann zu StackOverflowException
während der Serialisierung führen, insbesondere bei komplexen Objekten. Dies ist häufig auf die unendliche Rekursion innerhalb des internen Serialisierungsprozesses von JSON.NET zurückzuführen. Während die direkte Verwendung von JsonConvert.SerializeObject()
mit Ihrem benutzerdefinierten Konverter die empfohlene Lösung ist, werden in diesem Abschnitt alternative Ansätze untersucht, wenn das Attribut erforderlich ist.
1. Verfeinerung der WriteJson
Methode
Der Kern des Problems liegt häufig in der WriteJson
Methode Ihres benutzerdefinierten Konverters. Eine unzureichende Behandlung von Randfällen kann die Endlosschleife auslösen. Die folgende verbesserte WriteJson
-Methode befasst sich mit mehreren häufigen Szenarios:
<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>
Diese Version verarbeitet explizit Nullwerte und verwendet den Vertragslöser, um Eigenschaften zu durchlaufen, wobei ignorierte Eigenschaften und solche, bei denen ShouldSerialize
„false“ zurückgibt, übersprungen werden. Außerdem wird die Serialisierung korrekt an den Konverter der Eigenschaft delegiert, sofern einer vorhanden ist und schreiben kann, andernfalls wird der Serialisierer direkt verwendet.
2. Rekursiver Aufruf mit Stapelgrößenbeschränkung
Alternativ können Sie Ihrer WriteJson
-Methode eine Stapeltiefenprüfung hinzufügen, um eine außer Kontrolle geratene Rekursion zu verhindern:
<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>
Dieser Ansatz löst eine beschreibende Ausnahme aus, wenn die Rekursionstiefe einen vordefinierten Grenzwert überschreitet, wodurch das StackOverflowException
verhindert wird. Passen Sie MaxStackSize
basierend auf der Komplexität Ihres Objekts an.
Fazit
Während das Attribut [JsonConvert]
praktisch ist, erfordert die Verwendung mit benutzerdefinierten Konvertern sorgfältige Überlegung. Durch die Verbesserung Ihrer WriteJson
-Methode zur Behandlung von Randfällen und/oder die Integration einer Stapelgrößenprüfung können Sie das Risiko von StackOverflowException
während der Serialisierung effektiv mindern. Denken Sie daran, dass der manuelle Aufruf von JsonConvert.SerializeObject()
nach wie vor der sicherste und zuverlässigste Ansatz ist.
Das obige ist der detaillierte Inhalt vonWarum führt die Verwendung der Annotation „[JsonConvert()]' mit benutzerdefinierten JsonConvertern manchmal zu einer StackOverflowException und wie kann ich dies verhindern?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!