Newtonsoft Json.Net serialize JObject doesn't ignore nulls, even with the right settings
A "null"
value in a JObject
is actually a non-null JValue
with JValue.Type
equal to JTokenType.Null
. It represents a JSON value of null when such a value actually appears in the JSON. I believe it exists to capture the difference between the following two JSON objects:
"source2": {
"z": null
}
"source2": {
}
In the first case, the property "z"
is present with a null
JSON value. In the second case, the property "z"
is not present. Linq-to-JSON represents the first case with a null-type JValue
rather than having JProperty.Value
actually be null.
To prevent null tokens from creeping into your JObject
's values, use the appropriate serializer setting when creating the JObject
from some POCO:
var jobj = JObject.FromObject(new
{
x = 1,
y = "bla",
z = (int?)null
}, new JsonSerializer { NullValueHandling = NullValueHandling.Ignore } );
(Note the POCO must not itself already be a JObject
. The untyped method(s) JsonConvert.DeserializeObject(jsonString)
or JsonConvert.DeserializeObject<dynamic>(jsonString)
will by default return a JObject
when root JSON container in jsonString
is a JSON object.)
JSON.NET serialize JObject while ignoring null properties
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
Need to ignore NULL values when deserializing JSON
NullValueHandling.Ignore
will ignore null values for the relevant property of your model when serializing.
When deserialzing, you might consider deserializing to an IEnumerable<ChartData>
then using Linq to filter out the objects you don't want, based on what is, after all, custom logic: "exclude objects that have close == null".
E.g. (untested air code):
var data = JsonConvert.DeserializeObject<IEnumerable<ChartData>>(content,jsonSettings)
.Where(cd => cd.close != null)
;
var observableData = new ObservableCollection<ChartData>(data);
How to ignore a property in class if null, using json.net
As per James Newton King: If you create the serializer yourself rather than using JavaScriptConvert there is a NullValueHandling
property which you can set to ignore.
Here's a sample:
JsonSerializer _jsonWriter = new JsonSerializer {
NullValueHandling = NullValueHandling.Ignore
};
Alternatively, as suggested by @amit
JsonConvert.SerializeObject(myObject,
Newtonsoft.Json.Formatting.None,
new JsonSerializerSettings {
NullValueHandling = NullValueHandling.Ignore
});
Related Topics
Which Blocking Operations Cause an Sta Thread to Pump Com Messages
Using Statement with Generics: Using Iset<> = System.Collections.Generic.Iset<>
Jquery Ajax Call to an ASP.NET Webmethod
Get Values from Process Standardoutput
How to Use Npm with ASP.NET Core
Most Efficient Method of Self Referencing Tree Using Entity Framework
How to Cast Object to Its Actual Type
Are Structs Always Stack Allocated or Sometimes Heap Allocated
Use Dbcontext in Asp .Net Singleton Injected Class
How to Create Custom Propertygrid Editor Item Which Opens a Form
Using Tfs API, How to Find the Comments Which Were Made on a Code Review
Does Foreach Evaluate the Array at Every Iteration
Discovering Derived Types Using Reflection
How to Draw Shapes in Winforms