Json.NET Ignore null values in dictionary

南笙酒味 提交于 2019-12-23 12:17:14

问题


When serializing a dictionary with JSON.NET, it seems like the NullValueHandling setting is ignored.

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

Output:

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

I expected that only the KVP with key "A" is present in the json output and KVP "B" is omitted.

How can I tell Json.NET to only serialize the entries that do not contain null values?


回答1:


I would just filter out the null values from the original dictionary with LINQ and serialize the filtered dictionary:

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

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

            Console.WriteLine (json);
        }
    }
}

Which gives:

{
  "A": "Some text"
}



回答2:


The NullValueHandling setting is only applicable to class properties and not dictionaries. There doesn't appear to be a built-in way in JSON.NET to ignore null values in a dictionary.

If you want JSON.NET to handle this case for you, then you can create a custom JSON converter and override the WriteJson method to handle the null values.

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 key in dictionary.Keys)
        {
            if (dictionary[key] != null)
            {
                writer.WritePropertyName(key);

                serializer.Serialize(writer, dictionary[key]);
            }
        }

        writer.WriteEndObject();
    }
}

Which then you can use like this:

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



回答3:


The main idea of serialization is that after deserialization you should have the same object back. Most likely that is illogical to leave out keys with null values from a dictionary because keys per se represent some data. But that is ok to not save null fields because after deserialization you would still have the same object because these fields would be initialized to null by default.

And, this would work fine for class fields if they are nulls. Look at this example:

public class Movie
{
    public string Name { get; set; }
    public string Description { get; set; }
    public string Classification { get; set; }
    public string Studio { get; set; }
    public DateTime? ReleaseDate { get; set; }
    public List<string> ReleaseCountries { get; set; }
}

Movie movie = new Movie();
movie.Name = "Bad Boys III";
movie.Description = "It's no Bad Boys";

string ignored = JsonConvert.SerializeObject(movie,
    Formatting.Indented,
    new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });

// {
//   "Name": "Bad Boys III",
//   "Description": "It's no Bad Boys"
// }

In your case values for certain keys are nulls, but that's not the same as in the documentation provided.

This might help you, but you should be aware of how ToDictionary affects performance:

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


来源:https://stackoverflow.com/questions/53996646/json-net-ignore-null-values-in-dictionary

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!