FSharp.SystemTextJson
FSharp.SystemTextJson copied to clipboard
How to upgrade from 0.17.4 for single case unions and skippable fields?
Hello, we were using the 0.17.4 version of the library and would like to upgrade it to the latest version of this library. However, we have a lot of serialized documents stored that can't be deserialized using the same options that we were using in 0.17.4.
Are we missing some configuration to deserialize as we did in 0.17.4? Or is this an instance of a bug?
Here's an example input that we cannot deserialize:
type SingleCaseUnion = SingleCaseUnion of string
type ToDeserialize =
{
SingleCaseUnion : SingleCaseUnion
SkippableMember: int option
}
let exampleBody = """
{
"singleCaseUnion": {
"Case": "SingleCaseUnion",
"Fields": [
"some value"
]
}
}"""
Here are the options that we used back then:
module Serializer =
let options =
let opt = JsonSerializerOptions(JsonSerializerDefaults.Web)
let jsonUnionEncodings = JsonUnionEncoding.UnwrapFieldlessTags ||| JsonUnionEncoding.UnwrapOption
opt.Converters.Add(JsonFSharpConverter(jsonUnionEncodings, unionTagCaseInsensitive = true))
opt
let deserialize<'a> (body : string) =
JsonSerializer.Deserialize<'a> (body, options)
I see that SkippableOptionsField was added and is now required for the skippable member. If I'm not mistaken, We can use UnionAdjacentTag to deserialize the single case union.
I also see that we have to switch to the Fluent JsonFSharpOptions to be able to use SkippableOptionsField. So I tried with the following configuration:
module Serializer =
let options =
let opt =
JsonFSharpOptions()
.WithUnwrapOption()
.WithUnionUnwrapFieldlessTags()
.WithUnionTagCaseInsensitive()
.WithAllowNullFields()
.WithSkippableOptionFields()
.WithUnionAdjacentTag()
.ToJsonSerializerOptions()
opt.Converters.Add(JsonFSharpConverter())
opt
let deserialize<'a> (body : string) =
JsonSerializer.Deserialize<'a> (body, options)
However, we get this error:
System.Text.Json.JsonException: Missing field for record type Playground.Types+ToDeserialize: SingleCaseUnion
at [email protected](String x)
at System.Text.Json.Serialization.JsonRecordConverter`1.ReadRestOfObject(Utf8JsonReader& reader, Boolean skipFirstRead)
at System.Text.Json.Serialization.JsonRecordConverter`1.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.JsonCollectionConverter`2.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TCollection& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.DeserializeAsObject(Utf8JsonReader& reader, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadAsObject(Utf8JsonReader& reader, JsonTypeInfo jsonTypeInfo)
at System.Text.Json.Serialization.JsonListConverter`1.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo`1 jsonTypeInfo, Nullable`1 actualByteCount)
at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 json, JsonTypeInfo`1 jsonTypeInfo)
at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
at Playground.Serializer.deserialize[a](String body) in C:\Users\AlexGagné\RiderProjects\Playground\Playground\Deserializer.fs:line 36
at Playground.Program.main(String[] _arg1) in C:\Users\AlexGagné\RiderProjects\Playground\Playground\Program.fs:line 72
As if the AdjacentTag was being ignored? Or am I misunderstanding something?