将Nullable <DateTime>序列化为XML

我想序列化一个类的几个数据成员是Nullable对象,这里是一个例子

[XmlAttribute("AccountExpirationDate")] public Nullable<DateTime> AccountExpirationDate { get { return userPrincipal.AccountExpirationDate; } set { userPrincipal.AccountExpirationDate = value; } } 

但是,在运行时我得到的错误

无法序列化System.Nullable`1 [System.DateTime]types的成员'AccountExpirationDate'。 XmlAttribute / XmlText不能用于编码复杂的types。

但是我检查和Nullable是一个SerializableAttribute 。 我究竟做错了什么?

您只能将其序列化为XmlElement ,而不是XmlAttribute ,因为该表示对于某个属性来说太复杂。 这是例外情况告诉你的。

如果你只是想要它的工作 ,那么也许:

 using System; using System.ComponentModel; using System.Xml.Serialization; public class Account { // your main property; TODO: your version [XmlIgnore] public Nullable<DateTime> AccountExpirationDate {get;set;} // this is a shim property that we use to provide the serialization [XmlAttribute("AccountExpirationDate")] [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public DateTime AccountExpirationDateSerialized { get {return AccountExpirationDate.Value;} set {AccountExpirationDate = value;} } // and here we turn serialization of the value on/off per the value [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public bool ShouldSerializeAccountExpirationDateSerialized() { return AccountExpirationDate.HasValue; } // test it... static void Main() { var ser = new XmlSerializer(typeof(Account)); var obj1 = new Account { AccountExpirationDate = DateTime.Today }; ser.Serialize(Console.Out, obj1); Console.WriteLine(); var obj2 = new Account { AccountExpirationDate = null}; ser.Serialize(Console.Out, obj2); } } 

这将只包含有非空值时的属性。

我多次使用过这样的东西。

 [XmlIgnore] public Nullable<DateTime> AccountExpirationDate { get { return userPrincipal.AccountExpirationDate; } set { userPrincipal.AccountExpirationDate = value; } } /// /// <summary>Used for Xml Serialization</summary> /// [XmlAttribute("AccountExpirationDate")] public string AccountExpirationDateString { get { return AccountExpirationDate.HasValue ? AccountExpirationDate.Value.ToString("yyyy/MM/dd HH:mm:ss.fff") : string.Empty; } set { AccountExpirationDate = !string.IsNullOrEmpty(value) ? DateTime.ParseExact(value, "yyyy/MM/dd HH:mm:ss.fff") : null; } } 

定义封装你的funcionality的序列化。

这里是和例子。

 [XmlAttribute("AccountExpirationDate")] public SerDateTime AccountExpirationDate { get { return _SerDateTime ; } set { _SerDateTime = value; } } /// <summary> /// Serialize DateTime Class (<i>yyyy-mm-dd</i>) /// </summary> public class SerDateTime : IXmlSerializable { /// <summary> /// Default Constructor when time is not avalaible /// </summary> public SerDateTime() { } /// <summary> /// Default Constructor when time is avalaible /// </summary> /// <param name="pDateTime"></param> public SerDateTime(DateTime pDateTime) { DateTimeValue = pDateTime; } private DateTime? _DateTimeValue; /// <summary> /// Value /// </summary> public DateTime? DateTimeValue { get { return _DateTimeValue; } set { _DateTimeValue = value; } } // Xml Serialization Infrastructure void IXmlSerializable.WriteXml(XmlWriter writer) { if (DateTimeValue == null) { writer.WriteString(String.Empty); } else { writer.WriteString(DateTimeValue.Value.ToString("yyyy-MM-dd")); //writer.WriteString(SerializeObject.SerializeInternal(DateTimeValue.Value)); } } void IXmlSerializable.ReadXml(XmlReader reader) { reader.ReadStartElement(); String ltValue = reader.ReadString(); reader.ReadEndElement(); if (ltValue.Length == 0) { DateTimeValue = null; } else { //Solo se admite yyyyMMdd //DateTimeValue = (DateTime)SerializeObject.Deserialize(typeof(DateTime), ltValue); DateTimeValue = new DateTime(Int32.Parse(ltValue.Substring(0, 4)), Int32.Parse(ltValue.Substring(5, 2)), Int32.Parse(ltValue.Substring(8, 2))); } } XmlSchema IXmlSerializable.GetSchema() { return (null); } } #endregion 

我陷入了类似的问题。 我有一个在WCF服务中暴露的类中的date时间属性(如XmlAttribute)。

下面是我面临的和解决scheme:1)XmlSerializer类没有序列化可空types的XmlAttribute

 [XmlAttribute] public DateTime? lastUpdatedDate { get; set; } Exception thrown : Cannot serialize member 'XXX' of type System.Nullable`1. 

2)一些postbuild议用[XmlElement(IsNullable = true)]replace[XmlAttribute]。 但是这会将属性作为一个完全无用的元素进行序列化。 然而,它对XmlElements工作正常

3)一些build议在你的类中实现IXmlSerializable接口,但是这不允许从WCF消费应用程序中调用WCF服务。 所以这在这种情况下也不起作用。

解答:

不要将属性标记为空,而应使用ShouldSerializeXXX()方法来放置约束。

 [XmlAttribute] public DateTime lastUpdatedDate { get; set; } public bool ShouldSerializelastUpdatedDate () { return this.lastUpdatedDate != DateTime.MinValue; // This prevents serializing the field when it has value 1/1/0001 12:00:00 AM }