5
votes

Json.NET Ignorer les valeurs nulles dans le dictionnaire

Lors de la sérialisation d'un dictionnaire avec JSON.NET, il semble que le paramètre NullValueHandling soit ignoré.

{
  "A": "Some text",
  "B": null
}

Sortie:

var dict = new Dictionary<string, string>
{
    ["A"] = "Some text",
    ["B"] = null
};

var json = JsonConvert.SerializeObject(dict, Formatting.Indented,
    new JsonSerializerSettings
    {
        NullValueHandling = NullValueHandling.Ignore
    });

Console.WriteLine(json);


3 commentaires

Mettre à jour dict pour ne pas inclure de valeurs nulles puis sérialiser?


Pourquoi vous ne filtrez pas d'abord le dict, obtenez simplement les données ne contenant pas de valeur nulle. C'est plus facile :))


Comme vous avez déjà accepté une réponse, j'écris ici pour attirer votre attention sur le problème dans votre code. Très probablement, il est illogique de ne pas enregistrer les valeurs null du tableau, cela signifie que vous perdez certaines données, avec des champs de classe différents, car la nouvelle instance aura de toute façon ces champs et ils seront initialisés à null par défaut.


3 Réponses :


2
votes

L'idée principale de la sérialisation est qu'après la désérialisation, vous devriez avoir le même objet. Il est probablement illogique d'omettre des clés avec des valeurs null d'un dictionnaire, car les clés en soi représentent certaines données. Mais c'est correct de ne pas enregistrer les champs nuls car après la désérialisation, vous auriez toujours le même objet car ces champs seraient initialisés à null par défaut.

Et cela fonctionnerait bien pour les champs de classe si ce sont des null s. Regardez cet exemple :

var json = JsonConvert.SerializeObject(dict.Where(p => p.Value != null)
    .ToDictionary(p => p.Key, p => p.Value), Formatting.Indented);


0 commentaires

3
votes

Je filtrerais simplement les valeurs null du dictionnaire d'origine avec LINQ et sérialiserais le dictionnaire filtré:

{
  "A": "Some text"
}

Ce qui donne:

using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;

namespace JsonSerialize {
    public static class Program {
        private static Dictionary<string, string> dict = new Dictionary<string, string> {
            ["A"] = "Some text",
            ["B"] = null
        };

        public static void Main(string[] args) {
            var filtered = dict
                .Where(p => p.Value != null)
                .ToDictionary(p => p.Key, p => p.Value);

            var json = JsonConvert.SerializeObject(filtered, Formatting.Indented);

            Console.WriteLine (json);
        }
    }
}


0 commentaires

3
votes

Le paramètre NullValueHandling ne s'applique qu'aux propriétés de classe et non aux dictionnaires. Il ne semble pas y avoir de moyen intégré dans JSON.NET d'ignorer les valeurs nulles dans un dictionnaire.

Si vous souhaitez que JSON.NET gère ce cas pour vous, vous pouvez créer un convertisseur JSON personnalisé et remplacer la méthode WriteJson pour gérer les valeurs nulles.

var json = JsonConvert.SerializeObject(dict, Formatting.Indented, new CustomJsonConverter());

Que vous pouvez alors utiliser comme ceci:

public class CustomJsonConverter : JsonConverter
{
    public override bool CanRead => false;

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Dictionary<string, string>);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var dictionary = (Dictionary<string, string>)value;

        writer.WriteStartObject();

        foreach (var pair in dictionary)
        {
            if (pair.Value != null)
            {
                writer.WritePropertyName(pair.Key);

                serializer.Serialize(writer, pair.Value);
            }
        }

        writer.WriteEndObject();
    }
}


0 commentaires