Maison >développement back-end >C++ >Pourquoi JSON.Net lance-t-il une exception StackOverflowException lors de l'utilisation de l'annotation JsonConvert et comment peut-elle être corrigée ?

Pourquoi JSON.Net lance-t-il une exception StackOverflowException lors de l'utilisation de l'annotation JsonConvert et comment peut-elle être corrigée ?

Patricia Arquette
Patricia Arquetteoriginal
2025-01-20 15:41:09232parcourir

Why Does JSON.Net Throw a StackOverflowException When Using the JsonConvert Annotation, and How Can It Be Fixed?

Résolution de l'exception StackOverflow de JSON.Net lors de l'utilisation de l'attribut JsonConvert

La sérialisation de classes aplaties à l'aide de l'attribut [JsonConvert] peut conduire à un StackOverflowException dans JSON.Net. Ce problème, contrairement à l'utilisation directe de SerializeObject, provient d'appels récursifs.

La solution : éviter la sérialisation récursive

Le problème vient de l'interaction des convertisseurs personnalisés et JsonConvert. Lorsqu'un convertisseur personnalisé (par exemple, [JsonConverter(typeof(FJson))]) est appliqué, sa méthode WriteJson est appelée. Si cette méthode, à son tour, appelle JsonConvert.SerializeObject (directement ou indirectement), une boucle récursive est créée, entraînant un débordement de pile.

Modification du code pour WriteJson

Pour éviter cette récursion, la méthode WriteJson doit être réécrite pour sérialiser chaque propriété individuellement, évitant ainsi l'appel récursif à JsonConvert.SerializeObject. Voici une implémentation révisée :

<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>

Explication :

Cette méthode WriteJson révisée parcourt chaque propriété de l'objet. Il vérifie les propriétés ignorées et les méthodes ShouldSerialize avant de sérialiser la valeur de chaque propriété directement à l'aide du sérialiseur, éliminant ainsi l'appel récursif et résolvant le StackOverflowException.

Conclusion :

En sérialisant directement les propriétés individuelles dans la méthode WriteJson du convertisseur personnalisé, nous brisons le cycle récursif, empêchant le StackOverflowException et garantissant une sérialisation fiable des classes aplaties. Cette approche fournit une solution robuste pour gérer des structures d'objets complexes au sein de JSON.Net.

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!

Déclaration:
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