FSharp.SystemTextJson icon indicating copy to clipboard operation
FSharp.SystemTextJson copied to clipboard

Deserializtion doesn't match serialization (DU) (alternatively: can't deserialize DU case from bare string)

Open aggieben opened this issue 3 years ago • 2 comments

I'm working on an API client and modeling the API error codes like this:

[<JsonFSharpConverter(unionEncoding = (JsonUnionEncoding.Default ||| JsonUnionEncoding.UnwrapFieldlessTags))>]
type ApiErrorCode = 
    | [<JsonPropertyName "missing_scope">] MissingScope
    | [<JsonPropertyName "invalid_limit">] InvalidLimit
    // ...

Using these flags, serialization works the way I expect it to:

let testError = {| error = MissingScope |}
JsonSerializer.Serialize(testError)

This produces {"error": "missing_scope"}, just as I expect it to.

However, deserialization of a record like this doesn't work.

let jsonString = @"{ ""error"": ""missing_scope""}"
let json = JsonSerializer.Deserialize<JsonElement>(jsonString)
json.GetProperty("error").Deserialize<ApiErrorCode option>() // throws JsonException

The last line throws the following exception: JsonException: Failed to parse type blahblahblah: expected object, found String

Is there a way to deserialize a bare string into a DU case?

aggieben avatar Sep 13 '22 16:09 aggieben

I pasted your code into fsi and it correctly returned Some MissingScope for the last line. What versions of .NET and FSharp.SystemTextJson are you using?

Tarmil avatar Sep 25 '22 13:09 Tarmil

I tested using LinqPad 7 with

  • whatever the latest .NET 6 was at the time; probably 6.0.5 or so
  • FSharp.SystemTextJson 0.19.13

aggieben avatar Oct 11 '22 18:10 aggieben