Newtonsoft Json.Net serialize JObject doesn't ignore nulls, even with the right settings

16,490

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.)

Share:
16,490

Related videos on Youtube

xlecoustillier
Author by

xlecoustillier

R&amp;D software architect, software developer, mostly .NET, Java/Kotlin and Javascript/Typescript Functional programming &amp; JS stack enthusiast

Updated on September 16, 2022

Comments

  • xlecoustillier
    xlecoustillier over 1 year

    I'm trying to serialize an object using Newtonsoft Json.Net.

    This object is an anonymous type filled with a lot of heterogenous things, mainly regular POCOs, but also some JObjects or JArrays.

    The thing is that when adding the NullValueHandling property to NullValueHandling.Ignore, every null property gets ignored, but only if it's part of a "regular" .Net object. Every null property inside a JObject or JArray remains.

    Here's a minimal example:

    var jobj = JObject.FromObject(new Anything{
        x = 1,
        y = "bla",
        z = null
    });
    
    var poco = new Foo {
       foo1 = "bar",
       foo2 = null
    };
    
    var serialized = JsonConvert.SerializeObject(new {
        source1 = poco,
        source2 = jobj
    }, Newtonsoft.Json.Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore});
    

    Is there a simple way to ignore those null values as well ? Did I miss some setting option ? Or do I have to deal with it manually ?

    • Jon Skeet
      Jon Skeet about 9 years
      It would really help if you could provide a short but complete program demonstrating the problem.
    • Binkan Salaryman
      Binkan Salaryman about 9 years
      A skipped null entry of an array would change the indices; in this case you need to deal with it manually.
    • erikkallen
      erikkallen about 9 years
      This code can't compile because 1) there is no Foo type (no, this is not nitpicking because the problem could potentially be in the definition of that type somehow), and 2) You can't assign the null literal to an anonymous type property.
  • xlecoustillier
    xlecoustillier about 9 years
    As simple as that. Thanks a lot!
  • Fawad Raza
    Fawad Raza over 7 years
    This doesn't work when anonymous object has a property of Array, which has objects with null property, basically, this does not check recursively.
  • dbc
    dbc over 7 years
    @Fwd079 - it does check recursively, but the setting does not apply to collection entries. From the docs: Ignore: Ignore null values when serializing and deserializing objects. To skip specific collection entries, see maybe Excluding specific items in a collection when serializing to JSON or JSON.Net custom contract serialization and Collections
  • Brian Rogers
    Brian Rogers over 5 years
  • Toolkit
    Toolkit about 5 years
    am I missing something or this doesn't work at all dotnetfiddle.net/WINNCL
  • dbc
    dbc about 5 years
    @Toolkit - your problem is that JsonConvert.DeserializeObject<dynamic>(str); actually constructs and returns a JObject, see dotnetfiddle.net/beqU8T. If you want to strip null properties from a JObject see JSON.NET serialize JObject while ignoring null properties.