Serializing a field of type Func <int, int> (or even a common delegate) with a DataContract / DataMember in WCF
I am trying to serialize the Func<int, int> field marked with [DataMember] class marked with the [DataContract] sign, the definition of the target or the definition of the Lambda expression is also part of the contract, or maybe even in the class itself.
I use a custom DataContractResolver that works fine when I uncheck the Func field, but when I check it, it does not allow the System.DelegateSerializationHolder type needed for serialization. I tried adding this type to my own DataContractResolver but cannot find it in the System namespace.
I could override it in the [OnDeserialized] method for each client class that uses this class, but then I will need to do this every time I use this class, which of course I would like to avoid (client classes are also part of DataContract ).
This serialization is used so far to save the state of the application on disk, so saving delegates (or even events that do not interest me) makes logical sense, since all this is part of the object graph.
So, how can I serialize this Func<int, int> using WCF DataContract ?
The problem is that it is not possible to use the standard WCF serializer by default - delegation of serialization will work only for .NET.
The solution is to use the NetDataContractSerializer . In your case with persistence context (or File context):
var context = new StreamingContext(StreamingContextStates.Persistence); var s = new System.Runtime.Serialization.NetDataContractSerializer(); var sb = new StringBuilder(); using (var writer = new XmlTextWriter(new StringWriter(sb))) { s.WriteObject(writer, new Test() { SomeFunc = (int i) => "Hi".Dump().Length }); } sb.ToString().Dump(); [DataContract] class Test { [DataMember] public Func<int, int> SomeFunc; } Note that the serializer will only support delegate information - this is great if you only use compilation methods for your delegates, but this will not work for dynamically compiled methods. Be warned.
It would also be nice to avoid anonymous functions - while they work, they can also change between different assemblies, as a result of which your permanent state will become invalid, possibly with catastrophic side effects. Do not forget that the delegate is serialized using the method + class name (and return type and arguments ...) - when changing the name, the permanent delegate points to a new method with the old name. Even with non-anonymous methods, try not to change methods that could be stored as delegates - ideally, using the original method signature to ensure backward compatible behavior if necessary.
If you ever support network serialization, just add StreamingContextStates .