2010-03-08 51 views
5

使用XmlSerializer序列化DateTime字段時,出現了奇怪的結果。使用XmlSerializer對DataType =「time」字段進行序列化

我有以下類:

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」元素包含一個時間wh ich看起來更像是這樣的:

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

......這就是我所期待的?

感謝

戴夫

+0

[Serializing DateTime to time without milliseconds and gmt](http://stackoverflow.com/questions/101533/serializing-datetime-to-time-without-milliseconds-and-gmt) – 2011-11-17 13:58:44

回答

1
+0

Wooo是for真實。看起來像一個骯髒的黑客我沒有更好的方法來做到這一點? – CraftyFella 2010-03-08 15:53:28

+1

@CraftyFella,你可以實現'IXmlSerializable',但是你需要爲所有的序列化邏輯提供一個實現。 – 2010-03-08 15:56:57

+1

據我所知,這是唯一的解決方案。當我必須這樣做時,我會用第二個屬性來做到這一點。如果你找到更好的解決方案,請讓我知道。一個解決方案,不涉及編寫自己的XmlSerializer – IordanTanev 2010-03-08 15:57:34

2

我有不同的使用問題,我自己...但是我試圖序列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

1

擴大我對其他答案之一的評論。

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> 
+0

謝謝..這是一個明確的選擇。也不知道UtcNow。 – CraftyFella 2010-03-09 09:53:00

1

我與其他的答案(我沒有寫完的時候,他們彈出)同意。它看起來不可能,直接的方式。 使用Reflector查看源代碼顯示時間值最終轉換爲具有以下硬編碼格式的System.Xml.XmlConvert.ToString的字符串:

HH:mm:ss.fffffffzzzzzz

因此,有兩個屬性,真正的是[XmlIgnore]和你自己構建的字符串是一個好方法。

+0

非常徹底的謝謝檢查出來.. – CraftyFella 2010-03-09 09:50:12

相關問題