C# - Xml Serialization for System.TimeSpan
Problem
Trying to Serialize a System.TimeSpan object to xml in .Net 2.0 will result in an empty tag in the XML and the data of the timespan object is lost on Deserialization.
This seems to be an oversight on part of the MS Development team, but so far (SP 1 for VS 2005) no fix has been issued.
Unfortunately, since System.TimeSpan is a sealed class, it is not possible to extend it to add the missing functionality.
Solution
Thankfully it is possible to create a wrapper class that allows serializing the object by exposing the .Ticks property on the TimeSpan object as a public property.
public class SerializableTimeSpan
{
TimeSpan m_timeSpan;
public SerializableTimeSpan ()
{
m_timeSpan = new TimeSpan();
}
public SerializableTimeSpan(TimeSpan ts)
{
m_timeSpan = new TimeSpan(ts.Ticks);
}
[XmlIgnore()]
public TimeSpan TimeSpan
{
get {return m_timeSpan;}
set { m_timeSpan = value;}
}
public long Ticks
{
get { return m_timeSpan.Ticks; }
set { m_timeSpan = new TimeSpan(value); }
}
}
The following usage example exposes the serializable interface for the member m_ts to the Xml Serializer through the wrapper class, while hiding the original interface. For added convenience, the wrapper is hidden from Intellisense so it doesn't show up while coding.
class test
{
private TimeSpan m_ts;
[XmlIgnore()] // Hide this member from the Serializer, since it doesn't work anyway
public TimeSpan Span
{
...
}
[EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] // Hide this member for Intellisense, since we don't care about it in code.
public SerializableTimeSpan XmlSpan
{
get { return new SerializableTimeSpan(m_ts);}
set { m_ts = value.TimeSpan;}
}
}
The resulting xml output looks something like this:
...
<XmlSpan>
<Ticks>360000000000</Ticks>
</XmlSpan>
...