2008-11-21 3 views
4

Работает, чтобы получить DateTimes для любого часового пояса. Я использую DateTimeOffset и строку, и атрибут XmlElement. Когда я делаю, я получаю следующее сообщение об ошибке:Как сериализовать на dateTime

[InvalidOperationException: 'dateTime' is an invalid value for the XmlElementAttribute.DataType property. dateTime cannot be converted to System.String.]
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter) +450

[InvalidOperationException: There was an error reflecting type 'System.String'.]
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter) +1621
System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +8750
System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter) +139
System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter) +1273

[InvalidOperationException: There was an error reflecting property 'creationTimeX'.] ...

Код:

[System.Xml.Serialization.XmlElement(ElementName = "creationTime", 
     DataType="dateTime")] 
public string creationTimeX 
    { 
     get 
     { 
      return this.creationTimeField.ToString("yyyy-MM-ddTHH:mm:sszzz"); 
     } 
     set 
     { 
      DateTimeOffset.TryParse(value, out this.creationTimeField); 
     } 
    } 

[System.Xml.Serialization.XmlIgnoreAttribute()] 
public System.DateTimeOffset creationTime 
{ 
    get { 
     return this.creationTimeField; 
    } 
    set { 
     this.creationTimeField = value; 
    } 
} 
+0

Только для запись. Остерегайтесь `DateTimeOffset`. При использовании сериализации WCF возникают проблемы с сериализацией `DateTimeOffset`. – 2012-02-21 16:51:11

ответ

2

Взгляните на этот StackOverflow вопрос о сериализации даты и UTC:

Best practices for DateTime serialization in .Net framework 3.5/SQL Server 2008

Нет необходимо создать специальное свойство только для того, чтобы выполнить сериализацию Тион.

+0

Комментарий говорит, что все это .. даже мысль время ISO позволяет ничего ... Если вы абсолютно положительно должны знать сам часовой пояс (т.е.вышеупомянутое может быть «Восточное стандартное время» или «Центральное дневное время»), вам необходимо создать свой собственный тип данных, который раскрывает эти фрагменты. Внедрение iXmlSerializer – 2008-11-21 17:21:14

+0

UTC - это старый способ (конечно, это сериализуется), но не отвечает на вопрос о сериализации DateTimeOffset (с соответствующим временным поясом). Прочитайте статью MSDN по этому вопросу, текущие рекомендации от Microsoft - DateTimeOffset для обработки/хранения и TimeZoneInfo для расчетов в любых временных зонах: http://msdn.microsoft.com/en-us/library/bb384267(v=vs .110) .aspx Только опции предназначены для использования другого сериализатора (DataContract или NetDataContract), добавления таких свойств, как обходной путь, который я добавил в статью MS connect, или создать вашу собственную структуру с UTC и идентификатором часового пояса, но это менее стандартно – 2014-04-15 12:10:12

0

Дэвид

Тип данных свойства (creationTimeX) является строка, а XmlSerialization тип данных "DATETIME". Вот почему вы получаете это исключение.

Вы можете исправить это путем изменения типа данных в DateTime

Также для выпуска текущего времени для любого часового пояса, вы должны применить DateTime.Now.ToUniveralTime и применить соответствующий шаблон DateTimeFormat на нем.

Шаги для них здесь

http://msdn.microsoft.com/en-us/library/k494fzbf.aspx

Благодаря -RVZ

+0

Не то, что мне нужно. Я хотел бы переопределить стандартный DateTime, чтобы мы могли указать ЛЮБОЙ временной зом .... например, DateTimeOffset. DataType для задав строк работает для положительное_целого, nonPositiveInteger и т.д ... но не работает для DateTime спасибо – 2008-11-21 15:56:44

1

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

Вы можете использовать DateTime.Ticks, чтобы получить значение, и у него есть конструктор, который занимает длинный (Int64).

2

Это то, что работает для меня

private const string DateTimeOffsetFormatString = "yyyy-MM-ddTHH:mm:sszzz"; 
private DateTimeOffset eventTimeField; 

[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)] 
public string eventTime 
{ 
    get { return eventTimeField.ToString(DateTimeOffsetFormatString); } 
    set { eventTimeField = DateTimeOffset.Parse(value); } 
} 
1

Используйте XmlConvert.ToDateTimeOffset() и .ToString() методы, чтобы правильно сериализации и де-сериализации DateTimeOffset в свойстве XmlSerializer обходной.

Полный пример в статье Microsoft Connect здесь, и подтверждение того, что, к сожалению, Microsoft не исправит эту оплошность (она должна была быть изначально поддерживается с помощью XmlSerializer как любой примитивный тип):

https://connect.microsoft.com/VisualStudio/feedback/details/288349/datetimeoffset-is-not-serialized-by-a-xmlserializer

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