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 内の複雑なオブジェクト構造を管理するための堅牢なソリューションを提供します。
以上がJsonConvert アノテーションを使用すると JSON.Net が StackOverflowException をスローするのはなぜですか?また、それを修正するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。