Newtonsoft.Json
Newtonsoft.Json copied to clipboard
[Question] In which cases JsonConvert.DeserializeObject<T>(string, JsonSerializerSettings) actually returns null?
I'm working with .NET core 3.1, C# 8 and nullable reference types enabled.
From the class library I'm writing, I'm referencing the version 12.0.3 of Newtonsoft JSON.
I noticed that, by calling JsonConvert.DeserializeObject<T>(string, JsonSerializerSettings?), I can get a null reference (Visual Studio analyzers detect a possible dereferencing of a null reference).
Notice that I'm calling the overload which takes a string and an instance of JsonSerializerSettings
. I'm only using the JsonSerializerSettings
in order to handle the possible deserialization errors (via the Error property).
The github source code confirms that the overload I'm calling can possible return a null reference, via the MaybeNull
attribute: take a look here for a confirmation.
My question is: in which cases newtonsoft JSON returns a null
reference when deserializing a JSON string to a .NET type ?
Usually it returns an object of the given type populated or having its properties at the default value for their type, I have never encountered a case where null
is returned instead.
JsonConvert.DeserializeObject<string>("null")
will return null
.
@TylerBrinkley thanks for the contibution.
I noticed that your code actually does not raise any warning inside of visual studio 2019, even with nullable reference types enabled.
The only way to get a warning is calling the other overload, the one taking a second parameter of type JsonSerializerSetting
.
So, in my opinion, one of the followings is true (maybe both of them):
-
apart from the mentioned
"null"
input case, there is some other subtle corner case for anull
reuturn value, involvingJsonSerializerSettings
in some way -
the type annotation for the library is not complete and even the overload of
JsonConvert.DeserializeObject\<T\>
taking only astring
parameter should be annoted as possibly returningnull
I think the single string
parameter overload just got missed when the library was annotated.
I'd imagine with custom converters you could conceivably return null
from a non "null"
input as well.
I think the single
string
parameter overload just got missed when the library was annotated.I'd imagine with custom converters you could conceivably return
null
from a non"null"
input as well.
@TylerBrinkley this definitely clarify the point.
To summarize the possibility of getting back a null
value is only relegated to corner cases. Apart from an exotic custom converter or the "null"
input case, we can stay sure that we never get a null
reference back. Correct ?
I think this is a useful information for the library users which have enabled the nullable reference types feature.
@TylerBrinkley do you now actually why JsonConvert.DeserializeObject<string>("null")
returns null? I think "null"
is not a correct JSON regarding to JSON format docs. So, I think more sense has the method throwing some ArgumentException that input string is not in JSON format.
@TylerBrinkley do you now actually why
JsonConvert.DeserializeObject<string>("null")
returns null? I think"null"
is not a correct JSON regarding to JSON format docs. So, I think more sense has the method throwing some ArgumentException that input string is not in JSON format.
It seems that the string "null"
is actually valid JSON. You can verify yourself here
@EnricoMassone you are right, thank you for the answer.
In RFC 7159 there is such definition:
JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and arrays).
so, null
, 1
, "text"
, true
are all valid JSONs.
Calling JsonConvert.DeserializeObject()
with "null"
will return null
when deserializing into a class, too.
e.g.
public class User
{
}
...
User user = JsonConvert.DeserializeObject<User>("null");
// Prints `true`
Console.WriteLine(user == null);
This means that if you have nullable reference types enabled and you want JsonConvert.DeserializeObject()
to return T
instead of T?
, you need to write a helper method.