2010-03-08 11 views
5

Si ottengono risultati strani durante la serializzazione di un campo DateTime tramite XmlSerializer.Serializzazione di un campo DataType = "time" utilizzando XmlSerializer

Ho la seguente classe:

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

quando chiamo l'uso XmlSerializer con il seguente codice di prova:

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

ottengo alcuni risultati strani, ecco il codice XML che viene prodotto:

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

Qualsiasi idea è come posso ottenere l'elemento "TheTime" per contenere un tempo in cui È più simile a questo:

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

... come quello che mi aspettavo?

Grazie

Dave

+0

possibile duplicato di [Serializing DateTime in time senza millisecondi e gmt] (http://stackoverflow.com/questions/101533/serializing-datetime-to-time-without-milliseconds-and-gmt) –

risposta

1

diano un'occhiata al questa domanda Serializing DateTime to time without milliseconds and gmt

+0

Wooo è quello per vero. Sembra uno scherzo sporco per me .. Non c'è un modo migliore per farlo? – CraftyFella

+1

@CraftyFella, è possibile implementare 'IXmlSerializable', ma è necessario fornire un'implementazione per tutta la logica di serializzazione. –

+1

per quanto ne so questa è l'unica soluzione. Quando devo farlo lo faccio con una seconda proprietà.Se trovi una soluzione migliore per favore fammelo sapere.Una soluzione che non comporta la scrittura del tuo XmlSerializer – IordanTanev

2

Ho avuto diversi problemi con questo me stesso ... ma stavo cercando di serializzare un oggetto TimeSpan. La soluzione era di avere due proprietà, una che conteneva TimeSpan, e una che fosse una rappresentazione in stringa del TimeSpan che è stata serializzata. Qui era il modello:

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

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

Tuttavia, con questo codice, il tempo viene stampato nel seguente formato:

<ScheduledTime>PT23H30M</ScheduledTime> 

The W3C definition of duration is here which explains it.

1

Espansione sul commento che ho fatto su una delle altre risposte.

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

serializzazione in questo modo:

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

Esempio di stampa:

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

Grazie .. questa è una scelta definitiva. Inoltre non sapeva di UtcNow. – CraftyFella

1

Concordo con le altre risposte (che non è stato fatto per iscritto quando saltate fuori). non sembra possibile, in modo diretto. Uno sguardo alla fonte con riflettore mostra che un valore temporale finisce per essere convertito in una stringa con lo System.Xml.XmlConvert.ToString, che ha un formato codificato di:

HH: mm: ss.fffffffzzzzzz

Quindi avere due proprietà, quella reale che è [XmlIgnore] e una stringa che si costruisce da soli è una buona strada da percorrere.

+0

Molto accurato grazie per averlo verificato .. – CraftyFella

Problemi correlati