简体   繁体   中英

Serialize DateTime property to XML in C#

I´ma programming student and I would like to know if it is possible to change the format of a date when I serialize it in a xml file. This date is an attribute of an ObservableCollection of objects "Loan", this objects have two DateTime properties, one of the dates is a nullable object. I serialize all the collection including the date.

I would like to obtain in the xml file:

<OutDate> 15-03-2014 </OutDate>
<!--If the date is null I don´t want to appear the node-->

And I´m getting this:

 <OutDate>2014-03-15T00:00:00</OutDate>
 <InDate xsi:nil="true" /> 

This is part of my code project: Part of my class Loan, already mark as serializable, looks like this:

    private string isbn;
    private string dni;
    private DateTime dateOut;
    private DateTime? dateIn;    
    // Setters and Gettters and constructors 

This is the method for serialize:

// I will pass three collections to this method loans, books and clients
public void SerializeToXML<T>(string file, string node, ObservableCollection<T> collection)
        {
            XmlRootAttribute root = new XmlRootAttribute(node);
            XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<T>), root);
            using (FileStream fs = new FileStream(file, FileMode.Create))
            {
                serializer.Serialize(fs, collection);
            }
        }

The call:

SerializeToXML<Loan>(_file, "Library", manager.LoansCollection);

Thnks.

If you don't want to implement IXmlSerializable , some DateTime to string conversion of a backing field should do the trick, something like this:

    public class Loan
    {
        [XmlIgnore]
        private DateTime _dateOut;

        public string OutDate
        {
            get { return _dateOut.ToString("dd-MM-yyyy"); }
            set { _dateOut = DateTime.Parse(value); }
        }
    }

Probably the simplest way to achieve this is to implement the IXmlSerializable interface on your class instead. Something along the following lines

public class Loan : IXmlSerializable
{
    public void WriteXml(XmlWriter writer)
    {
        if(dateIn.HasValue)
        {
            writer.WriteElementString("dateIn", dateIn.Value.ToString());
        }
    }
}

On the read you'll need to read the Element name, if it's dateIn set that, otherwise set the appropriate value. Basically checking to see if it exists in the XML.

Have a look at the XmlElement attribute class (in System.Xml.Serialization). If that doesn't work then this answer shows how to use a proxy property

[XmlElement("TheDate", DataType = "date")]
    public DateTime TheDate { get; set; }

I know it's late to get my answer marked as "the one", but you can have control over serialization without implementing complex interfaces or wrapping stuff as a workaround.

public DateTime? InDate { get; set }

public bool ShouldSerializeInDate()
{
    return InDate.HasValue;
}

The C# XML Serializer has a not so well documented functionality. Every public property can have a method for turning on or off the serialization of the property. The method has to be called: ShouldSerializeXYZ where XYZ is the exact name of the property that you want to control.

See: Xml serialization - Hide null values

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM