Serializing int64 inside discriminated unions generates incompatible JSON, in other words, the generated JSON cannot be deserialized back to original type.
After tracking down the issue at Fable.Remoting, I narrowed it down to the following code that doesn't work:
open Fable.Core
open Fable.Core.JsInterop
type SingleCase = SingleCase of int64
let input = SingleCase 20L
printfn "%A" (ofJson<SingleCase> (toJson input))
You will get the error:
Uncaught Error: Cannot deserialize into Test.SingleCase - Error (inflate): Input string was not in a correct format. - Data: '{"SingleCase":{"low":20,"high":0,"unsigned":false}}'
Note: the same issue happens even with unions of multiple cases.
The Fable JsonConverter on the server is also unable to deserialize the date {"low":20,"high":0,"unsigned":false} into a proper int64 and throws this exception:
System.Exception: Expecting int64 but got StartObject.
/*
rest of irrelevant stack strace
*/
where the StartObject indicates that the deserializer encountered an object literal where it was expecting int64
dotnet fable --version): 1.3.17 && replHi @Zaid-Ajaj! Thanks a lot for the report and sorry for replying late. At the end we're deprecating JSON serialization in Fable 2, and instead we're adding auto-decoders to Thoth so we'll have to solve this issue there (if it's still happening).
BTW, the good news is Reflection is already implemented in Fable 2, so Fable.Remoting will likely work with the alpha release 馃槃
Thanks for the reply, maybe I missed something so I have a couple of questions
At the end we're deprecating JSON serialization in Fable 2
Should I assume that ofJson<'t> and toJson will be completely removed from Fable.Core?
We're adding auto-decoders to Thoth
Were these the code-generated specialized functions to serialize/deserialize objects?
Reflection is already implemented in Fable 2
Awesome, I will soon be running the tests against Fable 2 to see how things are going, though if toJson and ofJson<'t> are/will be removed, I need to think of some else to make Fable.Remoting "just work"
Lastly, if is it not a big issue, can it still be fixed to the Fable 1.3.x branch?
@Zaid-Ajaj Indeed ofJson and toJson will be removed from Fable.Core.
But we will provide equivalent via Thoth.Json, the idea is by using Thoth.Json we will check the data of JSON and output nice error message if an error occur.
For example, if you have a property : Firstname : string then, we will check that the value in the JSON is indeed set and that it's a string. With current ofJson if the value of Firstname is null in the JSON you don't know it until you use it and get an undefined error in your code.
@MangelMaxime I took a closer look, very interesting way for deserialization, I wonder if it can handle the exhaustive test suite of Fable.Remoting, I will try it soon and otherwise I will be swarming you with issues :joy: 馃槣
Thank you :)
I think it will not pass the test suite yet. I need to had more primitive type like Dates for example :)
@alfonsogarciacaro This issue looks exactly like #1374 where the value (of type int64) inside the union is not toString()-ed when serialized and instead only the internal representation (the object literal with high/low/unsigned properties) is stringified
It has something to do with this block of code and the deflateValue can extended to solve the same issue for int64:
import { isLong } from './Long'
function deflateValue(v: any) {
if (isDate(v)) {
return deflateDate(v);
}
if (isLong(v)) {
return v.toJSON();
}
return v;
}