10

The return type shown in the docs for the JsonSerializer.Deserialize method all show the return type as nullable.

If you look at the deserialisation examples in the MS docs, you see that they are inconsistent, in that the first and third specify the return type as nullable...

WeatherForecast? weatherForecast = 
  JsonSerializer.Deserialize<WeatherForecast>(jsonString);

...whereas the second example misses off the ?, meaning it's non-nullable.

By experimenting, it seems that as long as you supply valid JSON (otherwise you get an exception), then the return value is always a non-null object of the specified type. If the property names don't match, then the returned object will have default values for those properties, but you never get a null reference - or at least, I couldn't find a way.

Anyone able to clarify? Is there a situation in which the method can return null, without throwing an exception? If not, why are the return types specified as nullable?

Thanks

Avrohom Yisroel
  • 8,555
  • 8
  • 50
  • 106
  • 2
    What if `jsonString` is `"null"`? :) – AKX May 17 '22 at 15:49
  • Examples may be partly from pre-Nullable era. – Fildor May 17 '22 at 15:57
  • @AKX then the method throws an exception, see the docs – Avrohom Yisroel May 17 '22 at 16:04
  • @Fildor Yeah, I wondered about that, or that it was just a mistake. I'm more interested to know if the method could actually return `null` at all. If it can't, then I don't need any checks. If it can, I need to code against that – Avrohom Yisroel May 17 '22 at 16:04
  • @AKX Ah, no, I'm wrong! I misread your comment as what is the string were `null`, in which case an exception would be thrown. However, if the string contains the text `"null"` then you do indeed get a null object. That's weird, as if it contains any other (as far as I can see) non-valid JSON, then you get an exception – Avrohom Yisroel May 17 '22 at 16:15
  • Baseline is: you can get `null`, an exception or the expected value. – Fildor May 17 '22 at 16:16
  • @Fildor yeah, so it seems. I wonder if there is any other way to get `null`. This seems like such an odd and unlikely occurrence that I would have expected it to return either `new()` or (more likely) throw an exception. – Avrohom Yisroel May 17 '22 at 16:23

1 Answers1

9

Yes, parsing valid JSON "null" with a JSON serializer have to return null.

WeatherForecast? weatherForecast = 
  JsonSerializer.Deserialize<WeatherForecast>("null");

Note that other valid JSON strings like "123", "\"bob\"", "[]" should cause an exception because none of them represent a valid object.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • 2
    Thanks for that. Seems odd to me that `"null"` is valid JSON, but hey, you learn new things every day – Avrohom Yisroel May 17 '22 at 20:02
  • @AvrohomYisroel https://www.json.org/json-en.html – Alexei Levenkov May 17 '22 at 20:43
  • 1
    Humour me. Please explain where in that document you see that `"null"` is valid JSON. It's not a collection of name/value pairs, nor is it an ordered list of values. It's just a string, and as far as I can see from that spec, a string isn't a valid JSON object. The fact that it has the value `"null"` doesn't seem to change anything, as I can't see anywhere in there that this is specified. Not being awkward, but as you linked to the spec, I'd like to understand how it allows `"null"`. Thanks again. – Avrohom Yisroel May 17 '22 at 21:59
  • @AvrohomYisroel json->element -> ws value ws -> value -> `null`. Note that null is represented in C# as `"null"` (C# string of 4 characters without quotes). – Alexei Levenkov May 17 '22 at 22:01
  • Sorry, I don't understand what you mean. I was looking at the two diagrams that show the structure of a JSON object, and don't see how what you just posted fits with that. Please can you explain in more detail. Thanks. – Avrohom Yisroel May 17 '22 at 22:03
  • @AvrohomYisroel grammar is on the right – Alexei Levenkov May 17 '22 at 22:04
  • I saw that, but didn't really understand it. I was looking in the main document, which supposedly explains the spec, and that didn't fit with what you suggested. Guess it doesn't really matter. I have the answer to my basic question, even if I don't really understand why it's valid JSON. Thanks again. – Avrohom Yisroel May 17 '22 at 22:28
  • @AvrohomYisroel consider reading https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form that explains basic of how grammar rules are written/used. In that particular case "json" is starting "non-terminal symbol" (one that does not show up in the text by itself), rule for it is "json: element" (JSON is one "element"). "Element" in turn is another non-terminal symbol defined as "element: ws value ws" (value surrounded by whitespaces); and finally "value" has 'null' (terminal symbol - present as-is in the text) as one of the options "value: ... |null|...". ... – Alexei Levenkov May 17 '22 at 23:30
  • Usually one expect "JSON" to describe object (i.e. `{ "a":1 }` that parsed with that grammar as json -> element -> ws value ws -> value -> object -> { members } -> { member } -> { string : element } -> { "a" : 1} (notice that starting part is the same json-> ws value ws -> value - `null` is just a different kind of "value" from JSON's point of view) – Alexei Levenkov May 17 '22 at 23:32