Using Newtonsoft.Json with F# records can lead to NullReferenceExceptions down the line instead of failing fast when deserialising in case of types mismatch
See original GitHub issueSource/destination types
These records:
type Foo1 =
{
Bar: int
Baz: string
}
type Foo2 =
{
BarBaz: Foo1
Baz: string
}
Steps to reproduce
let foo1 = { Bar = 69; Baz = "oof" }
let foo1json = JsonConvert.SerializeObject foo1
Console.WriteLine ("serialized foo1:" + foo1json)
let foo2 = JsonConvert.DeserializeObject<Foo2> foo1json
Console.WriteLine ("foo2.Baz==" + foo2.Baz)
let isBarBazNull = Object.ReferenceEquals(foo2.BarBaz, null)
Console.WriteLine ("foo2.BarBaz==null?" + isBarBazNull.ToString())
Actual behavior
The following is printed:
serialized foo1:{"Bar":69,"Baz":"oof"}
foo2.Baz==oof
foo2.BarBaz==null?True
Which means that examining foo2.BarBaz.Bar
could throw a NullReferenceExceptions, when precisely F# is a language that presumes to not have this kind of exceptions. Newtonsoft.Json should be fixed to not make F# worse 😃
Expected behavior
The line JsonConvert.DeserializeObject<Foo2> foo1json
should throw an exception because the members of the json document don’t match with the members of the record type.
Versions tested with: 11.0.2 and 12.0.2
Issue Analytics
- State:
- Created 4 years ago
- Reactions:2
- Comments:5
Top Results From Across the Web
c# - When using record types to deserialize JSON, how can ...
I am using Newtonsoft Json to deserialize JSON into C# record types. I'll provide examples below, but the theme of the challenge here...
Read more >Performance Tips
Here are some tips to make it go even faster. Reuse Contract Resolver; Optimize Memory Usage; JsonConverters; Manually Serialize; Benchmarks. Reuse Contract ...
Read more >Error when Deserialize Json Array - Help
Json.Linq.JArray'. Type mismatch could be due to mixing a file reference to 'C:\Users\Dell.nuget\packages\newtonsoft.json ...
Read more >Serialization Error Handling
The Error event is an event handler found on JsonSerializer. The error event is raised whenever an exception is thrown while serializing or...
Read more >How to Deserialize a Complex JSON Object in C# .NET
In this article, we are gonig to learn how to deserialize a complex JSON object using C# as our language of choice.
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Point of clarification: the code examples in the first message are describing records not discriminated unions.
I have this problem as well, and I believe it’s emblematic of problems with F# records and serialization:
FSharpType
andFSharpValue
module functions to do something like the following:FSharpType.IsRecordType
. if no, continue on current serialization strategy. if yes,FSharpValue.MakeRecord
with the appropriate type and field arguments to create a fully-hydrated and correct record with no missing fields.Over the process of making the field value array, optionality should be taken into account. IE if destination type is
'a option
and the key is not present, setNone
for that value. Any other missing value should be interpreted as a serialization failure, because F# records are more strict than C# classes.D’oh! just changed this thanks.