Closed pragmatrix closed 9 years ago
Hi, can you tell me what happens if you explicitly attach the [<Serializable>]
or [<AutoSerializable(true)>]
attributes to the types?
Attaching [<Serializable>]
is not possible, because it is not defined for PCLs, and when [<AutoSerializable(true)>]
is attached, it fails the same way:
[<AutoSerializableAttribute(true)>]
type Test = | Test
Nessos.FsPickler.NonSerializableTypeException : Type 'L14.Drawing.Test' is not serializable.
at Nessos.FsPickler.Utils.Exn`1.get_Value() in c:\Users\eirik\Development\nessos\FsPickler\src\FsPickler\Utils\Utils.fs:line 54
at Nessos.FsPickler.PicklerCache.Nessos-FsPickler-IPicklerResolver-Resolve[T]() in c:\Users\eirik\Development\nessos\FsPickler\src\FsPickler\PicklerGeneration\PicklerCache.fs:line 55
at Nessos.FsPickler.FsPicklerSerializer.Serialize[T](Stream stream, T value, FSharpOption`1 pickler, FSharpOption`1 streamingContext, FSharpOption`1 encoding, FSharpOption`1 leaveOpen) in c:\Users\eirik\Development\nessos\FsPickler\src\FsPickler\FsPickler\Serializer.fs:line 52
at <StartupCode$FsPickler>.$Serializer.Pickle@147.Invoke(T v) in c:\Users\eirik\Development\nessos\FsPickler\src\FsPickler\FsPickler\Serializer.fs:line 147
at Nessos.FsPickler.FsPicklerSerializer.Pickle[T](T value, FSharpOption`1 pickler, FSharpOption`1 streamingContext, FSharpOption`1 encoding) in c:\Users\eirik\Development\nessos\FsPickler\src\FsPickler\FsPickler\Serializer.fs:line 147
at SerializationTests.TestOTest.pickleTest() in C:\.....\l14\SerializationTests\Library1.fs:line 12
Here is the decompiled header of the class:
[AutoSerializable(true)]
[DebuggerDisplay("{__DebugDisplay(),nq}")]
[CompilationMapping(SourceConstructFlags.SumType)]
[StructLayout(LayoutKind.Auto, CharSet = (CharSet) 4)]
public class Test : IEquatable<Test>, IStructuralEquatable, IComparable<Test>, IComparable, IStructuralComparable
I see. In the current version you could circumvent this by defining a custom pickler.
Given that this might be too noisy a solution, it could be possible to add an attribute in FsPickler that forces this behaviour. Something like
[<EnsureSerializable>]
type Test = Test of string
But then FsPickler would need to be referenced from the PCL, which is not possible at the moment. And I also would not like to see this requirement in the future.
Something like a global FsPickler.AssumeSerializable<Test>(recursive : bool)
or a way to dynamically attach attributes to types may be needed here.
I see. Ok so we may have to go down the TypeDescriptor path.
After I failed to use Newtonsoft.Json as a stand-in, I've taken a look at the master branch today, saw FsPickler.DeclareSerializable()
, and tried it. So far this works quite well. Thanks!
I need to add some more tests before this makes it into a release, should be out soon.
It seems that F# union and record types can not be serialized when they are declared in an F# portable class library. I am getting
NonSerializableTypeException
s even when I want to serialize simple instances oftype Test = | Test
for example.The F# compiler does not attach the
[Serializable]
attribute to these types, because it's unsupported in PCLs.Is there any way to enforce the generation of the Picklers that are required for these types?