> 백엔드 개발 > C++ > 사용자 정의 JsonConverters와 함께 `[JsonConvert()]` 주석을 사용하면 때때로 StackOverflowException이 발생하는 이유는 무엇이며 이를 방지하려면 어떻게 해야 합니까?

사용자 정의 JsonConverters와 함께 `[JsonConvert()]` 주석을 사용하면 때때로 StackOverflowException이 발생하는 이유는 무엇이며 이를 방지하려면 어떻게 해야 합니까?

Patricia Arquette
풀어 주다: 2025-01-20 15:25:15
원래의
704명이 탐색했습니다.

Why does using the `[JsonConvert()]` annotation with custom JsonConverters sometimes result in a StackOverflowException, and how can I prevent it?

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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