I have an abstract class that I'm trying to serialize and deserialize the concrete implementations of. In my abstract base class I have this:
[DataContract]
public class MyAbstractBase
{
[DataMember]
public string Foo { get; set; }
// some other abstract methods that derived classes have to implement
}
And to that class I add a method to serialize:
public string SerializeBase64()
{
// Serialize to a base 64 string
byte[] bytes;
long length = 0;
MemoryStream ws = new MemoryStream();
DataContractSerializer serializer = new DataContractSerializer(this.GetType());
XmlDictionaryWriter binaryDictionaryWriter = XmlDictionaryWriter.CreateBinaryWriter(ws);
serializer.WriteObject(binaryDictionaryWriter, this);
binaryDictionaryWriter.Flush();
length = ws.Length;
bytes = ws.GetBuffer();
string encodedData = bytes.Length + ":" + Convert.ToBase64String(bytes, 0, bytes.Length, Base64FormattingOptions.None);
return encodedData;
}
This seems to work fine, in that it produces "something" and doesn't actually throw any errors.
Of course, the problem comes with deserialization. I added this:
public static MyAbstractBase DeserializeBase64(string s)
{
int p = s.IndexOf(':');
int length = Convert.ToInt32(s.Substring(0, p));
// Extract data from the base 64 string!
byte[] memorydata = Convert.FromBase64String(s.Substring(p + 1));
MemoryStream rs = new MemoryStream(memorydata, 0, length);
DataContractSerializer serializer = new DataContractSerializer(typeof(MyAbstractBase ), new List<Type>() { typeof(SomeOtherClass.MyDerivedClass) });
XmlDictionaryReader binaryDictionaryReader = XmlDictionaryReader.CreateBinaryReader(rs, XmlDictionaryReaderQuotas.Max);
return (MyAbstractBase)serializer.ReadObject(binaryDictionaryReader);
}
I thought by adding the "known types" to my DataContractSerializer, it would be able to figure out how to deserialize the derived class, but it appears that it doesn't. It complains with the error:
Expecting element 'MyAbstractBase' from namespace 'http://schemas.datacontract.org/2004/07/MyApp.Foo'.. Encountered 'Element' with name 'SomeOtherClass.MyDerivedClass', namespace 'http://schemas.datacontract.org/2004/07/MyApp.Foo.Bar'.
So any idea what I'm missing here?
I put together a simple demonstration of the problem on a dot net fiddle here:
http://dotnetfiddle.net/W7GCOw
Unfortunately, it won't run directly there because it doesn't include the System.Runtime.Serialization assemblies. But if you drop it into a Visual Studio project, it will serialize fine, but balks at deserialization.