How can I XML Serialize a DateTimeOffset Property?

Viewed 18078

The DateTimeOffset property I have in this class doesn't get rendered when the data is represented as Xml. What do I need to do to tell the Xml serialization to render that proper as a DateTime or DateTimeOffset?

[XmlRoot("playersConnected")]
public class PlayersConnectedViewData
{
    [XmlElement("playerConnected")]
    public PlayersConnectedItem[] playersConnected { get; set; }
}

[XmlRoot("playersConnected")]
public class PlayersConnectedItem
{
    public string name { get; set; }
    public DateTimeOffset connectedOn { get; set; }  // <-- This property fails.
    public string server { get; set; }
    public string gameType { get; set; }
}

and some sample data...

<?xml version="1.0" encoding="utf-8"?>
<playersConnected 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <playerConnected>
    <name>jollyroger1000</name>
    <connectedOn />
    <server>log1</server>
    <gameType>Battlefield 2</gameType>
  </playerConnected>
</playersConnected>

Update

I'm hoping there might be a way through an Attribute which I can decorate on the property...

Bonus Question

Any way to get rid of those two namespaces declared in the root node? Should I?

7 Answers

I'm also unsure of the best way, but here is what I did:

[XmlElement("lastUpdatedTime")]
public string lastUpdatedTimeForXml
{
  get { return lastUpdatedTime.ToString(); }
  set { lastUpdatedTime = DateTimeOffset.Parse(value); }
}
[XmlIgnore] 
public DateTimeOffset lastUpdatedTime;

To supplement @Peter's answer, if you're using an ADO.NET Entities model (.edmx), and hence all the access modifiers are generated automatically in partial classes, you can edit the T4 template (expand the .edmx file in the solution explorer and open YourEdmxFilename.tt) to make it generate DateTimeOffset types with the internal modifier instead of the default.

Simply replace the Property(EdmProperty) method with the one below:

public string Property(EdmProperty edmProperty)
{
    string typeName = _typeMapper.GetTypeName(edmProperty.TypeUsage);
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1} {2} {{ {3}get; {4}set; }}",
        typeName == "System.DateTimeOffset" || typeName == "Nullable<System.DateTimeOffset>" ? "internal" : Accessibility.ForProperty(edmProperty),
        typeName,
        _code.Escape(edmProperty),
        _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
        _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}
Related