C
C#2mo ago
possix

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:
#nullable enable
public class Test
{
public required string Foo { get; init; }
}
#nullable enable
public class Test
{
public required string Foo { get; init; }
}
- {} 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
FusedQyou
FusedQyou2mo ago
The concept of nulabillity only exists at compile time So you can totally set it to null because the rules no longer apply
FusedQyou
FusedQyou2mo ago
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
possix
possix2mo ago
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?
FusedQyou
FusedQyou2mo ago
Does it throw because of the required, though? I don't think it's that specifically
Pobiega
Pobiega2mo ago
required is also a compile-time thing It's just that reflection code, like JSON serialization, can see the required marker and change what it does
possix
possix2mo ago
yes 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.
FusedQyou
FusedQyou2mo ago
Ok well I guess it does read the required tag then But here's the thing null is a valid value, because you passed something
possix
possix2mo ago
but reflection and NullabilityInfoContext can see the ?, yes? Hence my confusion..
FusedQyou
FusedQyou2mo ago
required requires any value, and null counts here because the pair was specified