Reputation: 955
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?
Upvotes: 0
Views: 1390
Reputation: 20086
The problem is that, from the CLR perspective, the object referenced by t1
is not actually of type Module1.Tree
but rather of an unrelated, nested type Module1.Tree+_Leaf
. You need to inform the DataContractJsonSerializer
that 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.
var serializer = new DataContractJsonSerializer (
new List<Type> (typeof (Module1.Tree).GetNestedTypes ()) { // nested types
typeof (Module1.Tree), // root type
}.ToArray ()) ;
although I'd be a bit scared to write such code unless F# actually specifies exactly how it generates CLR types from algebraic types.
Upvotes: 3