I have data that is best described as "onion-like" in that each outer layer builds on the one below it. Below you will see a vastly simplified version (mine is several layers deeper but exhibits the same behavior at each level).
[CollectionDataContract]
public abstract class AbstractTestGroup : ObservableCollection<AbstractTest>
{
[DataMember]
public abstract string Name { get; set; }
}
[CollectionDataContract]
[KnownType(typeof(Test))]
public class TestGroup : AbstractTestGroup
{
public override string Name
{
get { return "TestGroupName"; }
set { }
}
[DataMember]
public string Why { get { return "Why"; } set { } }
}
[DataContract]
public abstract class AbstractTest
{
[DataMember]
public abstract string SayHello { get; set; }
}
[DataContract]
public class Test : AbstractTest
{
//Concrete class - members in this class get serialized
[DataMember]
public string Month { get { return "June"; } set { } }
public override string SayHello { get { return "HELLO"; } set { } }
}
I create an instance of TestGroup
and add Test
objects to it using the .Add
that comes with the ObservableCollection
.
When I serialize and de-serialize this structure I get the following
<TestGroup xmlns="http://schemas.datacontract.org/2004/07/WpfApplication2" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<AbstractTest i:type="Test">
<SayHello>HELLO</SayHello>
<Month>June</Month>
</AbstractTest>
</TestGroup>
The output has left off the DataMember
s in TestGroup
. As I get deeper in my onion, no DataMember
s that are higher are included (even from the abstract classes). I have tried adding [KnownType(typeof(TestGroup))]
to both TestGroup
and AbstractTestGroup
without success.
The question: Why am I not able to serialize the DataMember
Why
in the TestGroup
class?
Follow up question: Is there an alternative way to serialize and de-serialize a structure of this shape? I am planning on using the output locally to "load" the configuration the user specifies. I would prefer to not have to specify my own Serialization scheme if I can avoid it.
For those interested here is how I am generating the class, serializing, and de-serializing it.
TestGroup tg = new TestGroup();
tg.Add(new Test());
DataContractSerializer ser = new DataContractSerializer(typeof(TestGroup));
MemoryStream memoryStream = new MemoryStream();
ser.WriteObject(memoryStream, tg);
memoryStream.Seek(0, SeekOrigin.Begin);
string str;
using (StreamReader sr = new StreamReader(memoryStream))
str = sr.ReadToEnd();
Edit: For what it's worth I tried changing to using Serializable
instead and have the same issue.