Maison > développement back-end > C++ > Pourquoi mon attribut JsonConvert provoque-t-il une exception StackOverflowException lors de la sérialisation d'objets complexes ?

Pourquoi mon attribut JsonConvert provoque-t-il une exception StackOverflowException lors de la sérialisation d'objets complexes ?

DDD
Libérer: 2025-01-20 15:40:13
original
409 Les gens l'ont consulté

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

Dépannage de StackOverflowException dans JSON.Net avec l'attribut [JsonConvert]

Le problème :

La sérialisation d'objets complexes en JSON aplati à l'aide de l'attribut [JsonConvert] dans JSON.Net peut déclencher un StackOverflowException.

Cause fondamentale :

Le convertisseur personnalisé FJson fourni utilise une méthode récursive (WriteJson) pour écrire le graphique d'objet dans l'écrivain JSON. Cette approche récursive ne dispose pas de garanties suffisantes pour différents scénarios, ce qui entraîne des boucles infinies potentielles et des erreurs de débordement de pile. Ces scénarios incluent :

  • ShouldSerialize*() méthodes : les méthodes personnalisées déterminant la sérialisation des propriétés peuvent entraîner une récursion involontaire.
  • Valeurs nulles : une mauvaise gestion des valeurs nulles peut entraîner des problèmes.
  • Types de valeur (structs) : ces types de données peuvent ne pas être gérés correctement dans le processus récursif.
  • Attributs du convertisseur JSON : les convertisseurs existants sur les propriétés peuvent interférer avec la logique récursive.

Résolution :

La clé pour résoudre ce StackOverflowException réside dans l'amélioration de la méthode WriteJson du convertisseur FJson pour répondre à ces cas extrêmes. Une méthode WriteJson révisée est présentée ci-dessous :

<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>
Copier après la connexion

Cette version améliorée gère explicitement les valeurs nulles et intègre une méthode d'assistance ShouldSerialize pour gérer efficacement les méthodes ShouldSerialize*() personnalisées, empêchant ainsi la récursivité infinie qui mène au StackOverflowException. Il délègue également correctement la sérialisation aux convertisseurs existants, le cas échéant. Cette approche révisée devrait sérialiser de manière fiable les objets complexes sans rencontrer d'erreur de débordement de pile lorsqu'elle est utilisée avec l'attribut [JsonConvert].

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal