Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to distinguish between null value and value not provided in Json.Net? [duplicate]

Tags:

rest

c#

json.net

Using Json.net deserialization is there a way I can distinguish between null value and value that isn't provided i.e. missing key?

I'm considering this for partial object updates using PATCH requests and they would represent different intents:

  • Null -> set this property to null
  • Missing -> skip properties not provided

In javascript this is the difference between undefined and null.

The best I came up with for now is to use JObject.

like image 426
Kugel Avatar asked Mar 04 '14 00:03

Kugel


People also ask

How do you indicate a null value in JSON?

Passing a null value to any Corticon Server using JSON payloads is accomplished by either: Omitting the JSON attribute inside the JSON object. Including the attribute name in the JSON Object with a value of JSONObject. NULL.

Can JSON serialize null?

While the implementation itself was a breeze, unfortunately this still didnt work - CanConvert() is never called for a property that has a null value, and therefore WriteJson() is not called either. Apparently nulls are automatically serialized directly into null , without the custom pipeline.

Is JSON net the same as Newtonsoft JSON?

Thanks. Json.NET vs Newtonsoft. Json are the same thing. You must be trying to use the same code with different versions of Json.NET.

Is JSON net deprecated?

Despite being deprecated by Microsoft in . NET Core 3.0, the wildly popular Newtonsoft. Json JSON serializer still rules the roost in the NuGet package manager system for . NET developers.


1 Answers

I had the exact same issue and I stumbled on this question during my researches.

Unsatisfied by the general consensus, I created an extended Nullable struct, which I called Settable<T> for lack of imagination. Basically it is a nullable with an additional field, IsSet, which is true no matter which value you stored, as long as you stored something, and false only for default(Settable<T>), which is aliased as Settable<T>.Undefined.

A deserializer is going to write the Settable<T> only if he finds a corresponding property, in which case IsSet will be true. If the property is not included in the deserialized json, the default will be retained, which has IsSet == false. So, replacing your int? properties in your DTO type with a Settable is going to give you the required difference between undefined (or, more exactly, unspecified) and null.

Yay!

I uploaded the implementation into a repository on Github, for everyone to use (no warranty, use at your own risk, etc... I'm in hospital with 6 broken ribs and under painkillers: if something doesn't work it's YOUR fault):

https://github.com/alberto-chiesa/SettableJsonProperties

Edit: As for the comment about undefined serializing to null, I added a custom ContractResolver to handle Settable properties and updated the repository.

like image 50
A. Chiesa Avatar answered Sep 28 '22 08:09

A. Chiesa