I need some help on implementing a way to serialize a custom configuration. I started with the content of following example: Polymorphic custom configuration section
Reading the configuration works fine as expected but I can't save modifications of some configuration properties (e.g. changing property P1 to contain another string). While debugging the content of the different objects looks fine (section contains collection which contains three proxy items which itself contain an instance of Parent class). The item which has been changed (P1="") has the isModified flag set to true (as expected).
When calling config.Save() some strange behaviour comes up and after three days of investigation (even the Microsoft base classes) I can't manage to find out where the problem is. Here are some of my conclusions:
I added an override for each of the SerializeX methods (SerializeSection, SerializeElement and SerializeToXmlElement) and debbuged step by step through the code.
SerializeSection is called (as expected) with parameter parentElement which is not the section I want to serialize as the Collection property is empty (I would expect it to have the three instances which are part of the configuration file). Calling base.SerializeSection with this instead of parentElement resolves the problem
SerializeToXmlElement is called before SerializeElement and does contain an instance of XmlWriter (as expected)
SerializeElement is called right after SerializeToXmlElement and does not contain the instance of XmlWriter anymore
When entering the serialize methods of the collection object I would expect that the three elements of the collections are serialized. But instead of the three items the collection only contains one item which has been freshly initialized and thus has a Parent property returning null.
I know that there needs to be a custom SerializeElement method (propably on the Proxy class) which then calls _Parent.ProxySerializeElement(writer, serializeCollectionKey) for each element as it does for deserializing. But I can't manage to get it work. An override of SerializeElement doesn't work as the XmlWriter instance is always null (even though the Proxy class has some IsModified method to check if the Parent object has changed). In addition the Parent object is always null too, as soon as I enter this custom SerializeElement method.
Here are the code fragments I added to the example:
Parent.cs
new public bool IsModified { get { return IsModified(); } }
public virtual bool ProxySerializeElement(XmlWriter writer, bool serializeCollectionKey)
{
return SerializeElement(writer, serializeCollectionKey);
}
Proxy.cs
protected override bool IsModified()
{
bool isModified = base.IsModified();
return isModified || (Parent == null ? false : Parent.IsModified);
}
protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey)
{
bool serialize = base.SerializeElement(writer, serializeCollectionKey);
return serialize || (_Parent == null ? false : _Parent.ProxySerializeElement(writer, serializeCollectionKey));
}
It's driving me nuts that I can't get it to work. Maybe someone else can help me out.
Thx in advance!
Greetings, Stefi
Finally this worked for me. Maybe it helps someone else who's having the same problem. I'll post the complete code to keep it simple. It might not be the firstclass solution but it's working. I would appreciate if someone else could have a look at it and propose a better way.
What helped me to get it working is this article: https://www.codeproject.com/Articles/16466/Unraveling-the-Mysteries-of-NET-2-0-Configuration
My code was missing the elements collection (see ThingElement.cs).
thing.config
ExampleSection.cs
ExampleThingElementCollection.cs
ThingElement.cs (this class acts as proxy element)
SpecialThing.cs (parent class, e.g. base class if you have other which derive)
One.cs (parent class, e.g. base class if you have other which derive
Two.cs