23

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 ?

xlecoustillier
  • 16,183
  • 14
  • 60
  • 85
  • 3
    It would really help if you could provide a short but complete program demonstrating the problem. – Jon Skeet Mar 25 '15 at 14:35
  • 1
    A skipped `null` entry of an array would change the indices; in this case you need to deal with it manually. – Binkan Salaryman Mar 25 '15 at 14:37
  • 1
    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. – erikkallen Mar 25 '15 at 14:45
  • @erikkallen Ok for the second one, I typed it by hand, this comes from a real object in real life, but I can't act on them directly. Corrected. For the "there's no Foo type", you're right, this type is called Column, but this is irrelevant, as those objects are serialized flawlessly. – xlecoustillier Mar 25 '15 at 14:49

2 Answers2

44

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

dbc
  • 104,963
  • 20
  • 228
  • 340
  • 1
    As simple as that. Thanks a lot! – xlecoustillier Mar 25 '15 at 14:58
  • This doesn't work when anonymous object has a property of Array, which has objects with null property, basically, this does **not** check recursively. – Fawad Raza Nov 07 '16 at 16:57
  • 1
    @Fwd079 - it does check recursively, but the setting does not apply to collection entries. From the [docs](http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_NullValueHandling.htm): *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](https://stackoverflow.com/questions/20955722) or [JSON.Net custom contract serialization and Collections](https://stackoverflow.com/questions/38038793) – dbc Nov 07 '16 at 20:26
  • It doesn't apply if I have no control of creating the JObject. How to serialize it without null values? – Artemious Dec 25 '18 at 15:30
  • 1
    @Artemious See [JSON.NET serialize JObject while ignoring null properties](https://stackoverflow.com/q/33027409/10263) – Brian Rogers Dec 27 '18 at 20:37
  • am I missing something or this doesn't work at all https://dotnetfiddle.net/WINNCL – Toolkit Feb 21 '19 at 14:57
  • @Toolkit - your problem is that `JsonConvert.DeserializeObject(str);` actually constructs and returns a `JObject`, see https://dotnetfiddle.net/beqU8T. If you want to strip null properties from a `JObject` see [JSON.NET serialize JObject while ignoring null properties](https://stackoverflow.com/q/33027409/3744182). – dbc Feb 21 '19 at 17:44
1

Add the JsonProperty decorator above yourfield name :

    [JsonProperty("bookmark", NullValueHandling = NullValueHandling.Ignore)]
    public string Bookmark { get; set; }
Spyros
  • 540
  • 1
  • 7
  • 21