Zaid-Ajaj / Fable.Remoting

Type-safe communication layer (RPC-style) for F# featuring Fable and .NET Apps
https://zaid-ajaj.github.io/Fable.Remoting/
MIT License
272 stars 54 forks source link

Serialization issue with type implementing IEnumerable #278

Open Evangelink opened 2 years ago

Evangelink commented 2 years ago

Issue relates to #269 but is a little different.

With the code given on #269 making the type public solves the issue but the code sample was a little too simplified.

My real type is as follow:

type NonEmptyList<'T> =
    private { List: 'T list }

    member this.Head = this.List.Head
    member this.Tail = this.List.Tail
    member this.Length = this.List.Length
    member this.Item index = this.List.[index]

    interface IEnumerable<'T> with
        member this.GetEnumerator() = (this.List :> _ seq).GetEnumerator()

    interface IEnumerable with
        member this.GetEnumerator() = (this.List :> _ seq).GetEnumerator() :> IEnumerator

    interface IReadOnlyCollection<'T> with
        member this.Count = this.Length

and this time, even removing the private keyword (hence allowing a pubic ctor) still results in a serialization issue Cannot create and populate list type NonEmptyList.

This seems to be a known issue for Newtonsoft when implementing IEnumerable<T> (see for example https://stackoverflow.com/questions/36926867/deserializing-json-into-a-list-of-objects-cannot-create-and-populate-list-type) but the issue is solved on recent versions (see https://stackoverflow.com/a/36927705/4625433) as long as the type contains a public constructor accepting a IEnumerable<T> argument which isn't the case for our fsharp types.

I haven't dig deeper to understand if there is anything that could be done on your side but I thought that might be better to post it.

Zaid-Ajaj commented 2 years ago

I'll have a look!