【问题标题】:Serializing a DataType="time" field using XmlSerializer使用 XmlSerializer 序列化 DataType="time" 字段
【发布时间】:2010-03-08 15:28:08
【问题描述】:

使用 XmlSerializer 序列化 DateTime 字段时,我得到一个奇怪的结果。

我有以下课程:

public class RecordExample
{
    [XmlElement("TheTime", DataType = "time")]
    public DateTime TheTime { get; set; }

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

    public static bool Serialize(
        Stream stream, object obj, Type objType, Encoding encoding)
    {
        try
        {
            var settings = new XmlWriterSettings { Encoding = encoding };

            using (var writer = XmlWriter.Create(stream, settings))
            {
                var xmlSerializer = new XmlSerializer(objType);
                if (writer != null) xmlSerializer.Serialize(writer, obj);
            }

            return true;
        }
        catch (Exception)
        {
            return false;
        }
    }
}

当我使用以下测试代码调用 XmlSerializer 时:

var obj = new RecordExample 
{ 
    TheDate = DateTime.Now.Date, 
    TheTime = new DateTime(0001, 1, 1, 12, 00, 00) 
};

var ms = new MemoryStream();

RecordExample.Serialize(ms, obj, typeof(RecordExample), Encoding.UTF8);
txtSource2.Text = Encoding.UTF8.GetString(ms.ToArray());

我得到了一些奇怪的结果,这是生成的 xml:

<?xml version="1.0" encoding="utf-8"?>
<RecordExample 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <TheTime>12:00:00.0000000+00:00</TheTime>
    <TheDate>2010-03-08</TheDate>
</RecordExample>

任何想法都是我如何让“TheTime”元素包含一个看起来更像这样的时间:

<TheTime>12:00:00.0Z</TheTime>

...正如我所期待的那样?

谢谢

戴夫

【问题讨论】:

标签: c# .net xml xml-serialization


【解决方案1】:

我自己也遇到过不同的问题……但是我试图序列化一个 TimeSpan 对象。解决方案是拥有两个属性,一个包含 TimeSpan,另一个是 TimeSpan 的字符串表示,该字符串表示已被序列化。这是模式:

[XmlIgnore]
public TimeSpan ScheduledTime
{
    get;
    set;
}

[XmlElement("ScheduledTime", DataType="duration")]
public string XmlScheduledTime
{
    get { return XmlConvert.ToString(ScheduledTime); }
    set { ScheduledTime = XmlConvert.ToTimeSpan(value); }
}

但是,使用此代码,时间会以以下格式打印出来:

<ScheduledTime>PT23H30M</ScheduledTime>

The W3C definition of duration is here which explains it.

【讨论】:

    【解决方案2】:

    【讨论】:

    • Wooo 是真的。对我来说似乎是一个肮脏的黑客行为。没有更好的方法吗?
    • @CraftyFella,你可以实现IXmlSerializable,但是你需要为所有的序列化逻辑提供一个实现。
    • 据我所知,这是唯一的解决方案。当我必须这样做时,我会使用第二个属性来执行此操作。如果您找到更好的解决方案,请告诉我。不涉及编写自己的 XmlSerializer 的解决方案
    【解决方案3】:

    扩展我对其他答案之一的评论。

    public class RecordExample : IXmlSerializable
    {
        public DateTime TheTime { get; set; }
        public DateTime TheDate { get; set; }
    
        public XmlSchema GetSchema()
        {
            return null;
        }
    
        public void ReadXml(XmlReader reader)
        {
            // TODO : Deserialization logic here
        }
    
        public void WriteXml(XmlWriter writer)
        {
            writer.WriteElementString(
                "date", 
                this.TheDate.ToString("yyyy-MM-dd"));
    
            writer.WriteElementString(
                "time", 
                this.TheTime.ToString("hh:mm:ss.fK"));
        }
    }
    

    像这样序列化:

    var rc = new RecordExample()
    {
        TheDate = DateTime.Today,
        TheTime = DateTime.UtcNow
    };
    
    var serializer = new XmlSerializer(typeof(RecordExample));
    
    var ms = new MemoryStream();
    
    serializer.Serialize(ms, rc);
    
    ms.Seek(0, SeekOrigin.Begin);
    
    Console.WriteLine(new StreamReader(ms).ReadToEnd());
    

    输出示例:

    <?xml version="1.0"?>
    <RecordExample>
      <date>2010-03-08</date>
      <time>04:26:16.1Z</time>
    </RecordExample>
    

    【讨论】:

    • 谢谢..这是一个明确的选择。也不知道 UtcNow。
    【解决方案4】:

    我同意其他答案(当他们弹出时我还没有写完)。它看起来不像是可能的,以直接的方式。 使用 Reflector 查看源代码表明,时间值最终会通过 System.Xml.XmlConvert.ToString 转换为字符串,其硬编码格式为:

    HH:mm:ss.fffffffzzzzzz

    所以有两个属性,真正的一个是 [XmlIgnore] 和一个你自己构建的字符串是一个很好的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-28
      • 2010-12-31
      相关资源
      最近更新 更多