简体   繁体   中英

Serialize JSON object as per the condition using C# and Json.NET

I am serializing data from a database into JSON format using JSON.Net. But I am not able to get the result I expect.

I have to create JSON objects according to certain conditions like if my data for datamap is null then it should not be included in the JSON, and if it is not null then it should be included.

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

Output 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"
    }
  ]
}

Expected Output:

{
  "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"
    }
  ]
}

The [JsonExtensionData] attribute causes the key-value pairs in the marked dictionary to be serialized as if they were properties of the class containing the dictionary. This attribute is handled specially by Json.Net and thus the IgnoreEmptyEnumerablesResolver suggested by @Alex in the comments will not have an effect on it. But you could restructure your classes such that you don't need the attribute for datamapKey and datamapKey1 , and that would allow the resolver to work on those dictionaries when they are empty, giving you the output you want.

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

Demo fiddle: https://dotnetfiddle.net/Gw03gY


If you don't like that idea or don't want to modify your class structure, another option is to load your object instance into a JObject and use a recursive method to remove empty tokens from the hierarchy. This approach is covered in detail in How to omit/ignore/skip empty object literals in the produced JSON? .

Here is a demo fiddle showing that approach with your existing class structure: https://dotnetfiddle.net/jmNgYi

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM