I’m trying to serialize a class that inherits from a base class that implements IXmlSerializable.
The base class, called PropertyBag is a class that allows dynamic properties (credits to Marc Gravell).
I implemented IXmlSerializable so that the dynamic properties (stored in a Dictionary) are written as normal xml elements.
e.g.
When serializing a class Person with a public property (non dynamic) Name and a dynamic property Age, I would like for it to generate the following XML:
<Person>
<Name>Tim</Name>
<DynamicProperties>
<Country>
<string>USA</string>
</Country>
</DynamicProperties>
<Person>
I can get the part to work with the following implementation of WriteXml in the base PropertyBag class:
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteStartElement("DynamicProperties");
// serialize every dynamic property and add it to the parent writer
foreach (KeyValuePair<string, object> kvp in properties)
{
writer.WriteStartElement(kvp.Key);
StringBuilder itemXml = new StringBuilder();
using (XmlWriter itemWriter = XmlWriter.Create(itemXml))
{
// serialize the item
XmlSerializer xmlSer = new XmlSerializer(kvp.Value.GetType());
xmlSer.Serialize(itemWriter, kvp.Value);
// read in the serialized xml
XmlDocument doc = new XmlDocument();
doc.LoadXml(itemXml.ToString());
// write to modified content to the parent writer
writer.WriteRaw(doc.DocumentElement.OuterXml);
}
writer.WriteEndElement();
}
writer.WriteEndElement();
}
However, when serializing the Person class, it no longer serializes the normal (non dynamic) properties unless I overwrite the WriteXml method in Person (which I do not want to do). Is there any way that in the base class I can automatically add the static properties? I know I can do this manually using reflection, but I was wondering if there is some built-in functionality in the .Net Framework?
Marc, your answer on putting the FixedProperties in a seperate collection got me thinking that instead of inheriting from PropertyBag, I should create a property of that type.
So I created a PropertyBagWrapper class that my Person class inherits from and it works.
I won’t repeat all the code for the PropertyBag and the custom classes needed for ICustomTypeDescriptor implementation, you can find that here.
I did move the TypeDescriptionProvider attribute from the PropertyBag class to the PropertyBagWrapper class.
The PropertyBag class still has the same implementation for WriteXml() method as posted in the question.