使用 JsonConvert
屬性時解決 JSON.Net 的 StackOverflowException
使用 [JsonConvert]
屬性序列化扁平類別可能會導致 JSON.Net 中的 StackOverflowException
。 與直接使用 SerializeObject
不同,這個問題源自於遞迴呼叫。
解:避免遞歸序列化
問題是由自訂轉換器和JsonConvert
的相互作用引起的。 當套用自訂轉換器(例如 [JsonConverter(typeof(FJson))]
)時,將呼叫其 WriteJson
方法。 如果此方法依序呼叫 JsonConvert.SerializeObject
(直接或間接),則會建立遞歸循環,導致堆疊溢位。
WriteJson
為了防止這種遞歸,需要重寫 WriteJson
方法以單獨序列化每個屬性,避免遞歸呼叫 JsonConvert.SerializeObject
。 這是修改後的實作:
<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>
說明:
這個修改後的 WriteJson
方法迭代物件的每個屬性。 它會在使用序列化器直接序列化每個屬性的值之前檢查被忽略的屬性和 ShouldSerialize
方法,從而消除遞歸呼叫並解決 StackOverflowException
.
結論:
透過在自訂轉換器的 WriteJson
方法中直接序列化各個屬性,我們打破了遞歸循環,防止了 StackOverflowException
並確保扁平化類別的可靠序列化。 這種方法為管理 JSON.Net 中的複雜物件結構提供了一個強大的解決方案。
以上是為什麼 JSON.Net 在使用 JsonConvert 註解時會拋出 StackOverflowException,以及如何修復?的詳細內容。更多資訊請關注PHP中文網其他相關文章!