【问题标题】:Is it possible to make json.net skip serialize some default value in dictionary是否可以让 json.net 跳过序列化字典中的某些默认值
【发布时间】:2019-01-30 11:45:44
【问题描述】:

我想跳过一些与默认值相同的字典值。

这是该词典的简化代码

public Dictionary<int, Item> allItems;

public class Item
{
    public bool IsSelected;
    public List<string> SelectionInfo;
}

所以,截至目前,我的 JSON 输出如下所示:

"allItems": {
    "0": {
      "IsSelected": true,
      "SelectionInfo": [
        "yes",
        "maybe",
        "no"
      ]
    },
    "1": {
      "IsSelected": false,
      "SelectionInfo": []
    }
  }

我想跳过“1”但不要完全跳过它,至少保留密钥以便以后可以恢复。并在字典上有 0 和 1

像这样?

"allItems": {
    "0": {
      "IsSelected": true,
      "SelectionInfo": [
        "yes",
        "maybe",
        "no"
      ]
    },
    "1": { }
  }

我环顾四周,发现您可以使用 JsonConverter。但是我的案例 JSON 工具在另一个项目 (Utility.Please.TurnToJson(item);) 上,我想保持它的一致性,并且在所有项目中只使用一个 JSON。也许如果 JsonConverter 是唯一的选择,至少为我提供有关如何将自定义 JsonConverter 传递给该项目的解决方案。

///somewhat like this?
Utility.Please.TurnToJson(item, new List<object>(){
    typeof(Custom1),
    typeof(Custom2)
});

【问题讨论】:

标签: c# dictionary uwp json.net


【解决方案1】:

这是可以为您提供预期输出的 JsonConverter。

如果IsSelected = falseSelectionInfo 数组为空,转换器可以保留您的密钥。

public class MyCustomJsonConverter : JsonConverter
{
    public override bool CanRead
    {
        get { return false; }
    }

    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        JObject jObj = new JObject();
        if (value != null)
        {
            var dict = JObject.Parse(value as string)["allItems"].ToObject<Dictionary<string, Item>>();
            foreach (var item in dict)
            {
                JObject jObject = new JObject();

                if (item.Value.IsSelected == false && item.Value.SelectionInfo.Count == 0)
                {
                    jObj.Add(new JProperty(item.Key, new JObject()));
                }
                else
                {
                    jObj.Add(new JProperty(item.Key, JObject.FromObject(item.Value)));
                }
            }
        }

        JObject jMainObject = new JObject();
        jMainObject.Add(new JProperty("allItems", jObj));
        jMainObject.WriteTo(writer);
    }
}

用法:

string json = File.ReadAllText(@"Path to your json file");

string output = JsonConvert.SerializeObject(json, new MyCustomJsonConverter());

输出:

【讨论】:

  • 所以,我今天正好有机会测试一下。一旦我开始我的项目,我得到的第一件事就是 ArguementException 在这一行 var dict = JObject.Parse(value as string)["allItems"].ToObject&lt;Dictionary&lt;string, Item&gt;&gt;(); 我的字典是 int,我需要将它更改为 int 吗?还是保留为字符串?
  • 我认为您将其保留为字符串,因为您的 json 键在字符串中,这意味着它们用 "1", "2" 之类的引号而不是 1, 2 之类的整数包裹。所以 json 键总是字符串而不是 int,但是这些键的值是任何类型的,这意味着它可以是 int、string、boolean 等 :)
猜你喜欢
  • 2021-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-08
  • 2014-03-31
  • 1970-01-01
  • 1970-01-01
  • 2014-05-26
相关资源
最近更新 更多