0

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"
    }
  ]
}
Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
  • I think the `JsonPropertyAttribute` and its `NullValueHandling` is what you are looking for – Alex Jun 21 '19 at 06:14
  • Otherwise, if you requirement is to not serialize empty collections, take a look at this answer: https://stackoverflow.com/questions/34903151/how-to-omit-empty-collections-when-serializing-with-json-net – Alex Jun 21 '19 at 06:18
  • @Alex I have tried the above solution it is not working. – Krutik Shah Jun 21 '19 at 06:34

1 Answers1

2

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

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
  • How can I achieve below JSON based on the condition? { "datamapItems": [ { "paramName": "VE8321C", "datamapKey": { }, "min": "0", "max": "40" }, { "paramName": "VE8321C", "min": "0", "max": "40" }, { "paramName": "VE8321C", "datamapKey": { "module": 1, "id": 1391 }, "datamapKey1": { }, "min": "0", "max": "40" } ] } – Krutik Shah Jun 24 '19 at 10:44
  • Based on what condition? – Brian Rogers Jun 24 '19 at 14:45
  • Condition is regarding the data of JSON for e.g if paramName==VE8321C then allow null data else remove the null data. – Krutik Shah Jun 26 '19 at 05:52