2010-03-08 3 views
5

Я получаю нечетный результат при сериализации поля DateTime с помощью XmlSerializer.Сериализация поля DataType = "time" с использованием XmlSerializer

У меня есть следующий класс:

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> 

... как это то, чего я ожидал?

Благодаря

Dave

+0

Возможный дубликат [Сериализация DateTime во времени без миллисекунд и gmt] (http://stackoverflow.com/questions/101533/serializing-datetime-to-time-without-milliseconds-and-gmt) –

ответ

1

взглянуть на этот вопрос Serializing DateTime to time without milliseconds and gmt

+0

Wooo - это то, что для реальный. Кажется, это грязный хак для меня .. Нет ли лучшего способа сделать это? – CraftyFella

+1

@CraftyFella, вы можете реализовать 'IXmlSerializable', но тогда вам нужно предоставить реализацию для всей логики сериализации. –

+1

Насколько я знаю, это единственное решение. Когда я должен это сделать, я делаю это со вторым свойством. Если вы найдете лучшее решение, пожалуйста, дайте мне знать. Решение, которое не связано с написанием собственного XmlSerializer – IordanTanev

2

У меня были разные проблемы с этим сам ... однако я пытался сериализовать объект TimeSpan. Решение состояло в том, чтобы иметь два свойства, в которых хранился TimeSpan, и тот, который был строковым представлением TimeSpan, который получил Serialized. Здесь была картина:

[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

1

Я согласен с другими ответами (я не сделал писать, когда они выскочили). это не похоже, что это возможно, прямо. Посмотрите на источник с отражателем показывает, что значение времени заканчивается время преобразуется в строку с System.Xml.XmlConvert.ToString, который имеет жестко запрограммированный формат:

HH: MM: ss.fffffffzzzzzz

Таким образом, имея два свойства, реальный, являющийся [XmlIgnore], и ​​строкой, которую вы создаете сами, является хорошим способом.

+0

Очень полное спасибо, что проверили это. – CraftyFella

Смежные вопросы