簡體   English   中英

Json.NET 忽略字典中的空值

[英]Json.NET Ignore null values in dictionary

使用 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 中似乎沒有內置方法來忽略字典中的空值。

如果您希望 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 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 s,這對於類字段可以正常工作。 看看這個例子

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM