2

I want to serialize DateTime so that when DateTime is null I dont get the tag itself.

I have also set bool specified for the above but my problem is DateTime being of value type it will never be null hence the bool specified will always be true for it.

I even tried replacing DateTime to System.Nullable but I get Serialization Error when Sending request or receiving response from WebService.

Is there any way out ?

Simon Steele
  • 11,558
  • 4
  • 45
  • 67

2 Answers2

4

See this question, where Marc gives an excellent answer. Just add a ShouldSerializeMyDateTime method to your class :

public bool ShouldSerializeMyDateTime()
{
    return MyDateTime.HasValue;
}

Apparently this is an undocumented feature of XML serialization... You can also use a property named MyDateTimeSpecified

Community
  • 1
  • 1
Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • This doesn't work: `System.InvalidOperationException: IsNullable may not be set to 'false' for a Nullable type. Consider using 'System.DateTime'`. – Simon Steele Aug 06 '09 at 11:07
  • Why you have used public string MyDateTimeXML() –  Aug 06 '09 at 12:27
  • MyDateTime will not be serialized (`XmlIgnore`), instead MyDateTimeXML will be serialized in an element named "MyDateTime". Since it is of type string, it can be null, so it won't be serialized if it's null. This trick also allows better control on the formatting of a property – Thomas Levesque Aug 06 '09 at 12:32
  • I've used the 2nd technique before as well, but to serialize a TimeSpan if I recall correctly. – Robert Paulson Aug 09 '09 at 04:26
  • For mine to compile I tweaked the line: if (MyDateTime.HasValue) return XmlConvert.ToString(MyDateTime, XmlDateTimeSerializationMode.Unspecified); to if (MyDateTime.HasValue) return XmlConvert.ToString(MyDateTime.Value, XmlDateTimeSerializationMode.Unspecified); – Perhentian Aug 13 '09 at 18:21
  • @Perhenthian : you're right, I'll update the code accordingly. Thanks ! – Thomas Levesque Aug 13 '09 at 18:41
1

You will probably need to implement IXmlSerializable and manually serialize your type, you will then be able to use the Nullable<DateTime>. Here's an example:

public class MyData : IXmlSerializable
{
    public Nullable<DateTime> MyDateTime { get; set; }

    public void WriteXml(XmlWriter writer)
    {
        if (this.MyDateTime.HasValue)
        {
            writer.WriteStartElement("MyDateTime");
            writer.WriteValue((DateTime)this.MyDateTime);
            writer.WriteEndElement();
        }
    }

    public void ReadXml(XmlReader reader)
    {
        if (reader.ReadToDescendant("MyDateTime"))
        {
            this.MyDateTime = reader.ReadElementContentAsDateTime();
        }
    }

    public XmlSchema GetSchema()
    {
        return null;
    }
}

Using this:

MyData md = new MyData { MyDateTime = null };
XmlSerializer ser = new XmlSerializer(typeof(MyData));
using (var writer = XmlWriter.Create(@"d:\temp\test.xml"))
{
    ser.Serialize(writer, md);
}

using (var reader = XmlReader.Create(@"d:\temp\test.xml"))
{
    md = (MyData)ser.Deserialize(reader);
    WL(md.MyDateTime.HasValue);
}

Change that first line to MyDateTime = DateTime.Now to see the alternate behaviour. This writes and reads the MyDateTime value depending on whether it's present in the XML:

<?xml version="1.0" encoding="utf-8"?>
<MyData />

<?xml version="1.0" encoding="utf-8"?>
<MyData>
    <MyDateTime>2009-08-06T10:10:14.8311049+01:00</MyDateTime>
</MyData>
John Saunders
  • 160,644
  • 26
  • 247
  • 397
Simon Steele
  • 11,558
  • 4
  • 45
  • 67