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!