Json.NET忽略字典中的空值

时间:2019-01-01 15:26:56

标签: c# json.net

使用JSON.NET序列化字典时,NullValueHandling设置似乎被忽略了。

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

输出:

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

我希望json输出中仅包含键为“ A”的KVP,而省略了KVP“ B”。

如何告诉Json.NET仅序列化不包含空值的条目?

3 个答案:

答案 0 :(得分:2)

序列化的主要思想是在反序列化之后,您应该拥有相同的对象。从字典中遗漏带有null值的键很不合逻辑,因为键本身代表一些数据。但是,不保存空​​字段也是可以的,因为在反序列化之后您仍将拥有相同的对象,因为默认情况下这些字段将被初始化为null

而且,如果它们是null,则对于类字段也可以正常工作。查看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"
// }

在您的情况下,某些键的值为null,但这与提供的文档中的不同。

这可能会对您有所帮助,但是您应该了解ToDictionary如何影响性能:

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

答案 1 :(得分:2)

我只是使用LINQ从原始字典中过滤掉null值并序列化过滤后的字典:

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

哪个给:

{
  "A": "Some text"
}

答案 2 :(得分:2)

NullValueHandling设置仅适用于类属性,不适用于字典。 JSON.NET中似乎没有内置的方法可以忽略字典中的空值。

如果您希望JSON.NET为您处理这种情况,则可以创建一个自定义JSON转换器并重写WriteJson方法以处理空值。

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

那么您可以这样使用:

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