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 只序列化不包含空值的条目?

我只会使用 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);
            var json = JsonConvert.SerializeObject(filtered, Formatting.Indented);
            Console.WriteLine (json);
        }
    }
}

这给了:

{
  "A": "Some text"
}

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

如果您希望 JSON.NET 为您处理这种情况,则可以创建自定义 JSON 转换器并覆盖 WriteJson 方法来处理 null 值。

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

然后你可以像这样使用:

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

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

而且,如果类字段

null,这将适用于类字段。 请看这个例子:

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 s,但这与提供的文档不同。

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

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

相关内容

  • 没有找到相关文章

最新更新