You can use a recursive helper method like the one below to remove the null
values from your JToken
hierarchy prior to serializing it.
using System;
using Newtonsoft.Json.Linq;
public static class JsonHelper
{
public static JToken RemoveEmptyChildren(JToken token)
{
if (token.Type == JTokenType.Object)
{
JObject copy = new JObject();
foreach (JProperty prop in token.Children<JProperty>())
{
JToken child = prop.Value;
if (child.HasValues)
{
child = RemoveEmptyChildren(child);
}
if (!IsEmpty(child))
{
copy.Add(prop.Name, child);
}
}
return copy;
}
else if (token.Type == JTokenType.Array)
{
JArray copy = new JArray();
foreach (JToken item in token.Children())
{
JToken child = item;
if (child.HasValues)
{
child = RemoveEmptyChildren(child);
}
if (!IsEmpty(child))
{
copy.Add(child);
}
}
return copy;
}
return token;
}
public static bool IsEmpty(JToken token)
{
return (token.Type == JTokenType.Null);
}
}
Demo:
string json = @"
{
""Foo"": {
""P1"": null,
""P2"": ""hello world"",
""P3"": null,
""P4"": {
""P1"": 1,
""P2"": null,
""P3"": null
},
""FooArray"": [
{
""F1"": null,
""F2"": null,
""F3"": null
}
]
},
""Bar"": null
}";
JToken token = JsonHelper.RemoveEmptyChildren(JToken.Parse(json));
Console.WriteLine(token.ToString(Formatting.Indented));
Output:
{
"Foo": {
"P2": "hello world",
"P4": {
"P1": 1
},
"FooArray": [
{}
]
}
}
Fiddle: https://dotnetfiddle.net/wzEOie
Notice that, after removing all null values, you will have an empty object in the FooArray
, which you may not want. (And if that object were removed, then you’d have an empty FooArray
, which you also may not want.) If you want to make the helper method more aggressive in its removal, you can change the IsEmpty function to this:
public static bool IsEmpty(JToken token)
{
return (token.Type == JTokenType.Null) ||
(token.Type == JTokenType.Array && !token.HasValues) ||
(token.Type == JTokenType.Object && !token.HasValues);
}
With that change in place, your output would look like this instead:
{
"Foo": {
"P2": "hello world",
"P4": {
"P1": 1
}
}
}
Fiddle: https://dotnetfiddle.net/ZdYogJ