首页 > 解决方案 > 使用 C# 和 Json.NET 根据条件序列化 JSON 对象

问题描述

我正在使用 JSON.Net 将数据库中的数据序列化为 JSON 格式。但我无法得到我期望的结果。

我必须根据某些条件创建 JSON 对象,例如如果我的数据为datamapnull,则不应将其包含在 JSON 中,如果不为 null,则应将其包含在内。

public class DatamapKey
{
    [JsonExtensionData]
    public Dictionary<string, JToken> DatamapKeyFields = new Dictionary<string, JToken>();
}
public class DatamapKey1
{
    [JsonExtensionData]
    public Dictionary<string, JToken> DatamapKey1Fields = new Dictionary<string, JToken>();
}
public class DatamapItem
{
    [JsonExtensionData]
    public Dictionary<string, JToken> DatamapItemFields = new Dictionary<string, JToken>();
    public DatamapKey datamapKey { get; set; }
    public DatamapKey1 datamapKey1 { get; set; }
}
public class RootObject
{
    public List<DatamapItem> datamapItems { get; set; }
}

输出 JSON:

{
  "datamapItems": [
    {
      "datamapKey": {
        "module": 1,
        "id": 1391
      },
      "datamapKey1": {},
      "paramName": "VE8321C",
      "min": "0",
      "max": "40"
    },
    {
      "datamapKey": {},
      "datamapKey1": {},
      "paramName": "VE8321C",
      "min": "0",
      "max": "40"
    },
    {
      "datamapKey": {
        "module": 1,
        "id": 1391
      },
      "datamapKey1": {
        "module": 1,
        "id": 1391
      },
      "paramName": "VE8321C",
      "min": "0",
      "max": "40"
    }
  ]
}

预期输出:

{
  "datamapItems": [
    {
      "paramName": "VE8321C",
      "datamapKey": {
        "module": 1,
        "id": 1391
      },
      "min": "0",
      "max": "40"
    },
    {
      "paramName": "VE8321C",
      "min": "0",
      "max": "40"
    },
    {
      "paramName": "VE8321C",
      "datamapKey": {
        "module": 1,
        "id": 1391
      },
      "datamapKey1": {
        "module": 1,
        "id": 1391
      },
      "min": "0",
      "max": "40"
    }
  ]
}

标签: c#jsonjson.net

解决方案


[JsonExtensionData]属性导致标记字典中的键值对被序列化,就好像它们是包含字典的类的属性一样。此属性由 Json.Net 专门处理,因此@AlexIgnoreEmptyEnumerablesResolver在评论中建议的内容不会对其产生影响。但是你可以重组你的类,这样你就不需要 and 的属性datamapKeydatamapKey1这将允许解析器在它们为空时处理这些字典,从而为你提供你想要的输出。

public class DatamapItem
{
    [JsonExtensionData]
    public Dictionary<string, JToken> DatamapItemFields { get; set; } = new Dictionary<string, JToken>();
    public Dictionary<string, JToken> datamapKey { get; set; } = new Dictionary<string, JToken>();
    public Dictionary<string, JToken> datamapKey1 { get; set; } = new Dictionary<string, JToken>();
}

public class RootObject
{
    public List<DatamapItem> datamapItems { get; set; }
}

演示小提琴:https ://dotnetfiddle.net/Gw03gY


如果您不喜欢这个想法或不想修改您的类结构,另一种选择是将您的对象实例加载到 a 中JObject并使用递归方法从层次结构中删除空标记。如何在生成的 JSON 中省略/忽略/跳过空对象文字中详细介绍了此方法?.

这是一个演示小提琴,展示了使用现有类结构的方法:https ://dotnetfiddle.net/jmNgYi


推荐阅读