【问题标题】:Serialize Complex Type System.Nullable<System.DateTime>序列化复杂类型 System.Nullable<System.DateTime>
【发布时间】:2009-08-06 08:01:09
【问题描述】:

我想序列化 DateTime,这样当 DateTime 为 null 时,我就不会得到标签本身。

我还为上述设置了 bool,但我的问题是 DateTime 是值类型,它永远不会为 null,因此指定的 bool 将始终为 true。

我什至尝试将 DateTime 替换为 System.Nullable,但在发送请求或接收来自 WebService 的响应时出现序列化错误。

有什么办法吗?

【问题讨论】:

    标签: c# xml xml-serialization


    【解决方案1】:

    请参阅this question,其中 Marc 给出了很好的答案。只需在你的类中添加一个ShouldSerializeMyDateTime 方法:

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

    显然这是 XML 序列化的一个未记录的特性...您也可以使用名为 MyDateTimeSpecified 的属性

    【讨论】:

    • 这不起作用:System.InvalidOperationException: IsNullable may not be set to 'false' for a Nullable&lt;System.DateTime&gt; type. Consider using 'System.DateTime'.
    • 你为什么使用公共字符串 MyDateTimeXML()
    • MyDateTime 不会被序列化 (XmlIgnore),而是 MyDateTimeXML 将在名为“MyDateTime”的元素中序列化。由于是string类型,所以可以为null,所以如果为null就不会被序列化。这个技巧还可以更好地控制属性的格式
    • 我之前也使用过第二种技术,但如果我没记错的话,可以序列化 TimeSpan。
    • 为了我的编译,我调整了这一行: if (MyDateTime.HasValue) return XmlConvert.ToString(MyDateTime, XmlDateTimeSerializationMode.Unspecified); to if (MyDateTime.HasValue) return XmlConvert.ToString(MyDateTime.Value, XmlDateTimeSerializationMode.Unspecified);
    【解决方案2】:

    您可能需要实现IXmlSerializable 并手动序列化您的类型,然后您将能够使用Nullable&lt;DateTime&gt;。这是一个例子:

    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;
        }
    }
    

    使用这个:

    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);
    }
    

    将第一行更改为MyDateTime = DateTime.Now 以查看替代行为。这取决于它是否存在于 XML 中来写入和读取 MyDateTime 值:

    <?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>
    

    【讨论】:

    • 添加了一个例子,似乎对我有用!我认为这也适用于您的网络服务结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-19
    • 2017-05-05
    • 1970-01-01
    • 2018-04-29
    相关资源
    最近更新 更多