deserialize non-nullable
Hello, I want to deserialize JSON with
System.Text.Json.JsonSerializer
. I have classes with required
properties and it by default throws an exception if any required property is missing, which is nice, I guess. But why doesn't it throw exceptions when I have nullable reference types and the value is null:
- {}
is bad json - missing Foo; expected exception
- {"Foo": 23}
is bad json - 23 is not a string; expected exception
- {"Foo": null}
is surprisingly perfectly fine. However, I would expect an exception, because null is not a valid string value in this context (Foo's type is not annotated with ?
- string?
)
Is there any option that I can turn on to throw on null value? I didn't find one.
I think I understand that nullable ?
is only for static analysis, but I would still expect different behavior. The deserializer can check with reflection if the ?
is there, right? Am I missing something?10 Replies
The concept of nulabillity only exists at compile time
So you can totally set it to
null
because the rules no longer applyTry adding this method and validate the value is set and valid: https://learn.microsoft.com/en-us/dotnet/api/system.text.json.serialization.ijsonondeserialized.ondeserialized?view=net-8.0
IJsonOnDeserialized.OnDeserialized Method (System.Text.Json.Seriali...
The method that is called after deserialization.
I believe this whole system only got introduced in C#8 so before that you didn't even have proper indications. That's why it's optional
Ok, got it.
Just curious, what led the C# team to this decision where one c# feature (
required
, also new keyword) throws and the other (nullable reference type) does not?Does it throw because of the
required
, though? I don't think it's that specificallyrequired
is also a compile-time thing
It's just that reflection code, like JSON serialization, can see the required
marker and change what it doesyes according to the docs (https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/required-properties)
There are three ways to mark a property or field as required for JSON deserialization: By adding the required modifier, which is new in C# 11. By annotating it with JsonRequiredAttribute, which is new in .NET 7. By modifying the JsonPropertyInfo.IsRequired property of the contract model, which is new in .NET 7.
Require properties for deserialization - .NET
Learn how to mark properties as required for deserialization to succeed.
Ok well
I guess it does read the
required
tag then
But here's the thing null
is a valid value, because you passed somethingbut reflection and
NullabilityInfoContext
can see the ?
, yes? Hence my confusion..required
requires any value, and null
counts here because the pair was specified