2008-11-21 12 views
4

Travailler pour obtenir DateTimes pour n'importe quel fuseau horaire. J'utilise DateTimeOffset, et une chaîne, et un attribut XmlElement. Quand je fais, je reçois l'erreur suivante:Comment sérialiser à 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'.] ...

code:

[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

Juste pour la record. Méfiez-vous de 'DateTimeOffset'. Il y a quelques problèmes sérialisant 'DateTimeOffset' en utilisant la sérialisation de WCF. –

Répondre

2

Jetez un oeil à cette question StackOverflow sur les dates sérialisation et UTC:

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

Non besoin de créer une propriété spéciale juste pour accomplir la serializa tion.

+0

Le commentaire dit tout .. même pensé temps ISO permet tout ... Si vous absolument, positivement devez savoir le fuseau horaire lui-mêmece qui précède pourrait être l'heure normale de l'est ou l'heure avancée du centre), vous devez créer votre propre type de données qui expose ces pièces. Implémenter iXmlSerializer –

+0

UTC est l'ancienne méthode (assurez-vous que sérialiser) mais ne répond pas à la question sur la sérialisation de DateTimeOffset (avec le fuseau horaire pertinent). Lisez l'article MSDN sur le sujet, le conseil actuel de Microsoft est DateTimeOffset pour le traitement/stockage et TimeZoneInfo pour les calculs où les fuseaux horaires sont impliqués: http://msdn.microsoft.com/en-us/library/bb384267(v=vs .110) .aspx Seules les options sont d'utiliser un sérialiseur différent (DataContract ou NetDataContract), d'ajouter des propriétés comme la solution de contournement ajoutée à l'article MS connect, ou de créer votre propre structure avec UTC et timezone ID –

0

David

Le type de données de la propriété (creationTimeX) est une chaîne alors que le type de données XmlSerialization est "dateTime". C'est pourquoi vous obtenez cette exception.

Vous pouvez résoudre ce problème en changeant le type de données à DateTime

également pour votre question de l'heure pour tout le fuseau horaire, vous devez appliquer un DateTime.Now.ToUniveralTime et appliquer modèle DateTimeFormat approprié sur elle.

Les étapes de ce sont ici

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

Merci -RVZ

+0

Pas ce dont j'ai besoin. Je voudrais remplacer le standard DateTime, de sorte que nous puissions spécifier n'importe quel temps zome .... par exemple DateTimeOffset. specifing DataType pour cordes fonctionne pour positiveInteger, nonPositiveInteger etc ... mais ne fonctionne pas pour datetime grâce –

1

Je vous suggère de sérialiser DateTime en tant que long (ce qui est ce que l'implémentation utilise en interne pour stocker la valeur réelle).

Vous pouvez utiliser DateTime.Ticks pour obtenir la valeur et il a un constructeur qui prend un long (Int64).

+0

semble être juste une question d'utilisation du constructeur, mais cette discussion est utile: https://stackoverflow.com/questions/1489243/how-can-i-convert-ticks-to-a-date-format –

2

C'est ce qui a fonctionné pour moi

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

Utilisez les méthodes XmlConvert.ToDateTimeOffset() et .ToString() correctement sérialiser et désérialiser un DateTimeOffset dans une propriété de contournement XmlSerializer.

Échantillon complet dans l'article Microsoft Connect ici, et la confirmation que, malheureusement, Microsoft ne résoudra pas ce contrôle (il aurait dû être pris en charge en mode natif par XmlSerializer comme tout type primitif):

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