JSON.NET StackOverflowException 및 [JsonConvert]
속성
[JsonConvert]
속성을 사용자 정의 JsonConverter
에 적용하면 직렬화 중에 특히 복잡한 객체의 경우 StackOverflowException
이 발생할 수 있습니다. 이는 JSON.NET 내부 직렬화 프로세스 내의 무한 재귀로 인해 발생하는 경우가 많습니다. 사용자 정의 변환기와 함께 JsonConvert.SerializeObject()
을 직접 사용하는 것이 권장되는 솔루션이지만, 이 섹션에서는 속성이 필요할 때 대체 접근 방식을 살펴봅니다.
1. WriteJson
방법
문제의 핵심은 사용자 정의 변환기의 WriteJson
메서드에 있는 경우가 많습니다. 극단적인 경우를 제대로 처리하지 않으면 무한 루프가 발생할 수 있습니다. 다음과 같은 개선된 WriteJson
메서드는 몇 가지 일반적인 시나리오를 해결합니다.
<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>
이 버전은 null 값을 명시적으로 처리하고 계약 확인자를 사용하여 속성을 반복하고 무시된 속성과 ShouldSerialize
이 false를 반환하는 속성을 건너뜁니다. 또한 속성 변환기가 존재하고 쓸 수 있는 경우 해당 변환기에 직렬화를 올바르게 위임하고, 그렇지 않으면 직렬 변환기를 직접 사용합니다.
2. 스택 크기 제한이 있는 재귀 호출
또는 WriteJson
메서드 내에 스택 깊이 검사를 추가하여 폭주 재귀를 방지할 수 있습니다.
<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>
이 접근 방식은 재귀 깊이가 미리 정의된 제한을 초과하는 경우 설명 예외를 발생시켜 StackOverflowException
을 방지합니다. 개체 복잡성에 따라 MaxStackSize
을 조정하세요.
결론
[JsonConvert]
속성은 편리함을 제공하지만 사용자 정의 변환기와 함께 사용하려면 신중한 고려가 필요합니다. 극단적인 경우를 처리하기 위한 WriteJson
방법을 개선하거나 스택 크기 검사를 통합함으로써 직렬화 중 StackOverflowException
의 위험을 효과적으로 완화할 수 있습니다. JsonConvert.SerializeObject()
을 수동으로 호출하는 것이 가장 안전하고 신뢰할 수 있는 접근 방식이라는 점을 기억하세요.
위 내용은 사용자 정의 JsonConverters와 함께 `[JsonConvert()]` 주석을 사용하면 때때로 StackOverflowException이 발생하는 이유는 무엇이며 이를 방지하려면 어떻게 해야 합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!