2010-03-08 12 views
5

Ich bekomme ein seltsames Ergebnis, wenn ich ein DateTime-Feld mit XmlSerializer serialisiere.Serialisieren eines DataType = "time" -Feldes mit XmlSerializer

Ich habe die folgende Klasse:

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

Wenn ich die Verwendung der XmlSerializer mit dem folgenden Test Code aufrufen:

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

ich einige seltsame Ergebnisse zu erhalten, ist hier die xml, das produziert wird:

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

ist irgendeine Idee, wie ich das „thetime“ Element erhalten kann eine Zeit wh enthalten ich sehe eher so aus:

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

... wie habe ich das erwartet?

Dank

Dave

+0

möglich duplicate von [Serializing DateTime zu Zeit ohne Millisekunden und gmt] (http://stackoverflow.com/questions/101533/serializing-datetime-to-time-without-milliseconds-and-gmt) –

Antwort

1

werfen Sie einen Blick auf diese Frage Serializing DateTime to time without milliseconds and gmt

+0

Wooo ist das für echt. Scheint wie ein schmutziger Hack für mich .. Es gibt keinen schöneren Weg, dies zu tun? – CraftyFella

+1

@CraftyFella, Sie können 'IXmlSerializable' implementieren, aber dann müssen Sie eine Implementierung für die gesamte Serialisierungslogik bereitstellen. –

+1

Soweit ich weiß, ist dies die einzige Lösung. Wenn ich es tun muss, mache ich das mit der zweiten Eigenschaft. Wenn Sie eine bessere Lösung finden, lassen Sie es mich bitte wissen. Eine Lösung, die nicht beinhaltet Schreiben Sie Ihren eigenen XmlSerializer – IordanTanev

2

Ich selbst hatte mit dieser verschiedenen Fragen ... aber ein Timespan-Objekt zu serialisiert ich versuchte. Die Lösung sollte zwei Eigenschaften haben, eine, die die TimeSpan enthielt, und eine, die eine String-Repräsentation der TimeSpan war, die serialisiert wurde. Hier war das Muster:

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

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

jedoch mit diesem Code wird die Zeit in folgendem Format ausgedruckt:

<ScheduledTime>PT23H30M</ScheduledTime> 

The W3C definition of duration is here which explains it.

1

Erweitern Sie den Kommentar, den ich auf einer der anderen Antworten gemacht habe.

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

Serialisierung wie folgt aus:

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

Ausgabebeispiel:

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

Danke .. das ist eine definitive Option. Habe auch nichts von UtcNow gewusst. – CraftyFella

1

ich mit den anderen Antworten stimmen (Ich schrieb nicht getan, wenn sie auftauchte). es sieht nicht so aus, als ob es direkt möglich ist. Ein Blick auf die Quelle mit Reflektor zeigt, dass ein Zeitwert endet mit dem System.Xml.XmlConvert.ToString in eine Zeichenfolge konvertiert bis zu sein, das eine hartcodierte Format hat:

HH: mm: ss.fffffffzzzzzz

Also mit zwei Eigenschaften, die echte [XmlIgnore] und eine Zeichenfolge, die Sie selbst bauen, ist ein guter Weg zu gehen.

+0

Sehr gründliches Dankeschön für die Überprüfung .. – CraftyFella

Verwandte Themen