> 백엔드 개발 > C++ > 복잡한 객체를 직렬화할 때 내 JsonConvert 속성이 StackOverflowException을 발생시키는 이유는 무엇입니까?

복잡한 객체를 직렬화할 때 내 JsonConvert 속성이 StackOverflowException을 발생시키는 이유는 무엇입니까?

DDD
풀어 주다: 2025-01-20 15:40:13
원래의
409명이 탐색했습니다.

Why Does My JsonConvert Attribute Cause a StackOverflowException When Serializing Complex Objects?

[JsonConvert] 속성을 사용하여 JSON.Net에서 StackOverflowException 문제 해결

문제:

JSON.Net 내에서 [JsonConvert] 속성을 사용하여 복잡한 객체를 평면화된 JSON으로 직렬화하면 StackOverflowException.

근본 원인:

제공되는 FJson 사용자 정의 변환기는 재귀적 방법(WriteJson)을 사용하여 객체 그래프를 JSON 작성기에 씁니다. 이 재귀적 접근 방식은 다양한 시나리오에 대한 충분한 보호 장치가 부족하여 잠재적인 무한 루프 및 스택 오버플로 오류가 발생할 수 있습니다. 이러한 시나리오에는 다음이 포함됩니다.

  • ShouldSerialize*() 메서드: 속성 직렬화를 결정하는 사용자 지정 메서드는 의도하지 않은 재귀로 이어질 수 있습니다.
  • Null 값: Null 값을 잘못 처리하면 문제가 발생할 수 있습니다.
  • 값 유형(구조체): 이러한 데이터 유형은 재귀 프로세스 내에서 올바르게 처리되지 않을 수 있습니다.
  • JSON 변환기 특성: 속성의 기존 변환기가 재귀 논리를 방해할 수 있습니다.

해상도:

StackOverflowException 문제를 해결하는 열쇠는 WriteJson 변환기의 FJson 메서드를 개선하여 이러한 극단적인 경우를 해결하는 데 있습니다. 수정된 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 도우미 메서드를 통합하여 사용자 정의 ShouldSerialize*() 메서드를 효과적으로 관리함으로써 StackOverflowException으로 이어지는 무한 재귀를 방지합니다. 또한 적절한 경우 기존 변환기에 직렬화를 올바르게 위임합니다. 이 수정된 접근 방식은 [JsonConvert] 속성과 함께 사용할 때 스택 오버플로 오류가 발생하지 않고 복잡한 개체를 안정적으로 직렬화해야 합니다.

위 내용은 복잡한 객체를 직렬화할 때 내 JsonConvert 속성이 StackOverflowException을 발생시키는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿