Monday, 25 May 2009

How do you get TimeSpan properties to serialise to XML

I have just noticed that when using the XMLSerializer to write TimeSpan data to an XML output does not work - the public element is always written but is always blank!

Microsoft acknowledge the issue here
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=94492

Fortunately as always with these things not all is lost - and thanks to the web I have found a number of solutions...

http://stackoverflow.com/questions/637933/net-how-to-serialize-a-timespan-to-xml
http://lucaspirot.blogspot.com/2009/04/xml-serialization-and-timespan-bug.html

You could of course take on the serialisation by hand and format the entire object but this seems like hard work to me! Of course if your class has a large number of TimeSpan properties it may be worth the effort...

The two options best described by the two articles linked above both require a new property or public variable.

The first an I think most simple just requires a new property of type long which you now store your TimeSpan.Ticks value within it. Where in the example below StartTime was the original TimeSpan property - You can of course exclude the original TimeSpan property from the serialisation using the [XmlIgnore] attribute prior to the property.

[XmlElement("StartTimeTicks")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public long StartTimeTicks
{
get { return StartTime.Ticks; }
set { StartTime = new TimeSpan(value);}
}

The alternative to the this approach is to just add a public long variable, again to hold the TimeSpan ticks value. Rather than using the property setter and getters - which for this scenario I prefer, you can set up two new methods descorated with the [OnSerializing] and [OnDeserializing] attributes. So the serialisation method you assign the TimeSpan.Ticks value to the variable and the deserialisation method updates your actual TimeSpan property based on the ticks value deserialised.

Personally, whilst the later method works just as well it seems like a lot more work - of course now I think about it, if you have multiple TimeSpan properties that need to be managed you could use the latter method to centralise all of the logic in two methods rather than multiple getters and setters. Your call, I hope this may of helped!!

No comments:

Post a Comment