fahadash
fahadash

Reputation: 3281

Problems roundtripping F# discriminated unions with Json.net

I have the following enum in F#

 type MyEnum = 
    | Value1
    | Value2
    | Value3

This is what the compiler generates when the code compiles

   [Serializable]
    [DebuggerDisplay("{__DebugDisplay(),nq}")]
    public class MyEnum : IEquatable<MyEnum>, IStructuralEquatable, IComparable<MyEnum>, IComparable, IStructuralComparable
    {
        [CompilerGenerated]
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        [DebuggerNonUserCode]
        public bool IsValue1 { get; }
        [CompilerGenerated]
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        [DebuggerNonUserCode]
        public bool IsValue2 { get; }
        [CompilerGenerated]
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        [DebuggerNonUserCode]
        public bool IsValue3 { get; }
        [CompilerGenerated]
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        [DebuggerNonUserCode]
        public int Tag { get; }
        [CompilerGenerated]
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        [DebuggerNonUserCode]
        public static MyEnum Value1 { get; }
        [CompilerGenerated]
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        [DebuggerNonUserCode]
        public static MyEnum Value2 { get; }
        [CompilerGenerated]
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        [DebuggerNonUserCode]
        public static MyEnum Value3 { get; }

        [CompilerGenerated]
        public override sealed int CompareTo(MyEnum obj);
        [CompilerGenerated]
        public override sealed int CompareTo(object obj);
        [CompilerGenerated]
        public override sealed int CompareTo(object obj, IComparer comp);
        [CompilerGenerated]
        public override sealed bool Equals(MyEnum obj);
        [CompilerGenerated]
        public override sealed bool Equals(object obj);
        [CompilerGenerated]
        public override sealed bool Equals(object obj, IEqualityComparer comp);
        [CompilerGenerated]
        public override sealed int GetHashCode();
        [CompilerGenerated]
        public override sealed int GetHashCode(IEqualityComparer comp);

        public static class Tags
        {
            public const int Value1 = 0;
            public const int Value2 = 1;
            public const int Value3 = 2;
        }
    }

Problem When the above enum type is used for serialization which requires non-static set for each property for deserialization, it fails. In fact I have used it with RavenDB and Json.Net serialization and I get the following

myenummember = {}

How do I effectively make use of F# enum types with serializers ?

Upvotes: 2

Views: 1094

Answers (3)

Ruben Bartelink
Ruben Bartelink

Reputation: 61795

While Json.net 6.0(.1?) provides support for F# DUs, there are many weaknesses (some of which are mentioned in my answer and commentary in @John Palmer's link).

FsUno.Prod incorporates a Serialization.fs (written by Jérémie Chassaing) which addresses these concerns and more [using the technique @Ayende Rahien mentions].


(At this very instant my fork, FunDomain includes some further extensions) here. (The changes will likely end up back in FsUno.Prod which should be considered the authoratative repo)

Upvotes: 2

user1158550
user1158550

Reputation:

Try marking the type with the "Serializable" attribute. Also providing assignment for the pattern identifiers might help the compiler infer that it is a enum and not a sum type might help.

[<Serializable>]
type x =
  ABC = 1
| ABE = 2

Upvotes: -2

Ayende Rahien
Ayende Rahien

Reputation: 22956

You can provide JsonConverter instances that know how to translate this back & forth.

Upvotes: 2

Related Questions