Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to overwrite default collection on deserialization

I have a class which represents a bunch of settings:

public class Settings
{
   public Settings()
   {
       InnerSettings = new List<InnerSettings>();
       //this is the settings i want to have by default
       InnerSettings.Add(new InnerSettings());
   }
   [XmlArray]
   public List<InnerSettings> InnerSettings {get; set;}
}

Now, when I deserialize this object, the InnerSettings from XML are added to the List on top of the items which were created in default Settings() constructor. Is there an easy way to tell deserializer, that I want to overwrite the collection instead, removing the default items?

like image 604
Nikita B Avatar asked Feb 06 '26 04:02

Nikita B


1 Answers

XML Serializer doesn't support any callback and deriving from XmlSerializer class there are few methods you can override. Let's see some (dirty) workarounds:

1) Change default constructor (the one XmlSerializer will call) to do not include default item(s). Add a second constructor with a dummy parameter and expose a factory method:

public class Settings {
   private Settings() {
       // Called by XmlDeserializer
   }

   private Settings(int dummy) {
       // Called by factory method
       InnerSettings = new List<InnerSettings> { new InnderSettings(); }
   }

   public static Settings Create() {
       return new Settings(0);
   }
}

2) Remove items after object has been deserialized. Create your own XmlSerializer for this:

public class SettingsXmlSerializer : XmlSerializer {
    protected override object Deserialize(XmlSerializationReader reader) {
        var settings = (Settings)base.Deserialize(reader);
        settings.InnerSettings.RemoveAt(0);

        return settings;
    }
}

3) It should be right way to do it but it's not easy for complex types: the long job of IXmlSerializable implementation...

like image 141
Adriano Repetti Avatar answered Feb 08 '26 18:02

Adriano Repetti