I have a f# library with some values that I want to serialize in c# with json.
With registers I had no problems but I’m having errors when I try to serialize algebraic data types.
For example, lets say this is the f# module and I want to serialize t1.
module Module1=
type Tree = Leaf | Branch of Tree * int * Tree
let t1 = Leaf
In c# I do the following:
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Module1.Tree));
StreamWriter writer = new StreamWriter(@"c:\test");
serializer.WriteObject(writer.BaseStream, Module1.t1);
writer.Close();
I’m having this error(in spanish because my visual studio is in spanish :S )
“No se espera el tipo ‘ns.Module1+Tree+_Leaf’ con el nombre de contrato de datos ‘Module1.Tree._Leaf:http://schemas.datacontract.org/2004/07/ns‘. Agregue los tipos no conocidos estáticamente a la lista de tipos conocidos (por ejemplo, usando el atributo KnownTypeAttribute o agregándolos a la lista de tipos conocidos que se pasa a DataContractSerializer).”
my translation:
“The type ‘ns.Module1+Tree+_Leaf’ was not expected with the data contract name ‘Module1.Tree._Leaf:http://schemas.datacontract.org/2004/07/ns‘. Add the unknown types statically to the list of known types (for example, using the attribute KnownTypeAttribute or adding them to the list of known types that are passed to DataContractSerializer).”
Any ideas how to solve it?
The problem is that, from the CLR perspective, the object referenced by
t1is not actually of typeModule1.Treebut rather of an unrelated, nested typeModule1.Tree+_Leaf. You need to inform theDataContractJsonSerializerthat it may encounter objects of this type. Hopefully there is a helper method somewhere in the F# runtime to list such compiler-generated nested types; if not, you’ll have to use reflection, e.g.although I’d be a bit scared to write such code unless F# actually specifies exactly how it generates CLR types from algebraic types.