views:

136

answers:

2

I have a problem which I have been bashing my head against for the better part of three hours. I am almost certain that I've missed something blindingly obvious...

I have a simple XML file:

<?xml version="1.0" encoding="utf-8"?>
<WeightStore xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;  
  <Records>
    <Record actual="150" date="2010-05-01T00:00:00" />
    <Record actual="155" date="2010-05-02T00:00:00" />
  </Records>
</WeightStore>

I have a simple class structure:

[Serializable]
public class Record
{
    [XmlAttribute("actual")] public double weight { get; set; }
    [XmlAttribute("date")]   public DateTime date { get; set; }
    [XmlIgnore]              public double trend { get; set; }
}

[Serializable]
[XmlRoot("WeightStore")]
public class SimpleWeightStore
{
    [XmlArrayAttribute("Records")]
    private List<Record> records = new List<Record>();
    public List<Record> Records { get { return records; } }

    [OnDeserialized()]
    public void OnDeserialized_Method(StreamingContext context)
    {
        // This code never gets called
        Console.WriteLine("OnDeserialized");
    }
}

I am using these in both calling code and in the class files:

using System.Xml.Serialization;
using System.Runtime.Serialization;

I have some calling code:

SimpleWeightStore weight_store_reload = new SimpleWeightStore();
TextReader reader = new StringReader(xml);
XmlSerializer deserializer = new XmlSerializer(weight_store.GetType());
weight_store_reload = (SimpleWeightStore)deserializer.Deserialize(reader);

The problem is that I am expecting OnDeserialized_Method to get called, and it isn't.

I suspect it might have something to do with the fact that it's XML deserialization rather than Runtime deserialization, and perhaps I am using the wrong attribute name, but I can't find out what it might be.

Any ideas, folks?

+4  A: 

There's no equivalent of OnDeserialized for XML deserialization.

See this post for workarounds: http://stackoverflow.com/questions/1266547/how-do-you-find-out-when-youve-been-loaded-via-xml-serialization

Julien Lebosquain
Darn. That's very annoying. Oh well. I have added a workaround involving a field which gets unset when I deserialize, and set again when the internal state is good.
Jonathan
A: 

The only way you could do that in a graceful way is to manually implement IXmlSerializable, which is not fun. Simply; XmlSerializer doesn't support serialization callbacks.

Sometimes, though, you can switch to DataContractSerializer, which still offers xml capabilities but which does support serialization callbacks. Unfortunately the xml options are limited - it won't work for you xml structure, since that uses attributes (DataContractSerializer only supports elements).

You might also look at the comments on this answer, which discusses the points from this.

Marc Gravell