web-dev-qa-db-fra.com

Forcer XmlSerializer à sérialiser DateTime comme 'YYYY-MM-DD hh: mm: ss'

J'ai un schéma XSD pour certains services RESTful. Lorsqu'il est utilisé conjointement avec xsd.exe outil pour générer du code C #, XSD xs:date génère le code suivant:

[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, DataType="date")]
public System.DateTime time {
    get {
        return this.timeField;
    }
    set {
        this.timeField = value;
    }
}

Lors de la désérialisation de XML en objets à l'aide de XmlSerializer tout semble aller bien. Le problème auquel je suis confronté est que le service s'attend à ce que les dates soient formatées en YYYY-MM-DD hh:mm:ss et le code généré par XSD ne semble produire que YYYY-MM-DD.

Si je modifie XSD manuellement en xs:dateTime type, le code C # généré produit: 2010-08-20T20:07:03.915039Z.

Fondamentalement, comment puis-je forcer la sérialisation à produire YYYY-MM-DD hh:mm:ss? Y a-t-il quelque chose à faire pour XSD ou est-ce que je peux faire pour modifier le code C # généré?

63
wpfwannabe

Dans le passé, j'ai fait ce qui suit pour contrôler la sérialisation datetime:

  • Ignorez la propriété DateTime.
  • Créer une propriété de chaîne factice qui sérialise/désérialise comme je veux

Voici un exemple:

public class SomeClass
{
    [XmlIgnore]
    public DateTime SomeDate { get; set; }

    [XmlElement("SomeDate")]
    public string SomeDateString
    {
        get { return this.SomeDate.ToString("yyyy-MM-dd HH:mm:ss"); }
        set { this.SomeDate = DateTime.Parse(value); }
    }
}
125
kbrimington

Utilisez l'attribut [XmlElement(DataType = "date")] pour formater la valeur de votre propriété DateTime selon vos besoins.

à partir de MSDN :

Remarque:
L'attribut qui annote le champ date de publication a une propriété DataType. Il n'y a aucun type dans le .NET Framework qui correspond complètement au type xs: date. La correspondance la plus proche est System.DateTime, qui stocke les données de date et d'heure. La spécification de la propriété DataType comme une "date" garantit que le XmlSerializer ne sérialisera que la partie date de l'objet DateTime.

52
Bill Gates

Je pense que l'implémentation de l'interface IXmlSerializable fera l'affaire. Vous pouvez ensuite contrôler la façon dont vous sérialisez et désérialisez votre objet.

3
Eric

Si vous avez seulement besoin d'effacer la partie en millisecondes. Faire référence à:

Comment tronquer les millisecondes hors d'un .NET DateTime

Et fondamentalement, faites quelque chose comme:

  startDateTimeToUse = startDateTimeToUse.AddTicks(-(startDateTimeToUse.Ticks % TimeSpan.TicksPerSecond));
  endDate = endDate.AddTicks(-(endDate.Ticks % TimeSpan.TicksPerSecond));

Je peux confirmer que cela sérialise:

            <startDate>2015-10-31T12:13:04</startDate>
            <endDate>2016-11-10T12:13:06</endDate>

Je dois également déclarer que Avant d'effacer les millisecondes, je fais ceci:

            var startDateTimeToUse = ssStartDateTime.ToUniversalTime();
            var endDate = DateTime.Now.ToUniversalTime();
            startDateTimeToUse = DateTime.SpecifyKind(startDateTimeToUse, DateTimeKind.Unspecified);
            endDate = DateTime.SpecifyKind(endDate, DateTimeKind.Unspecified);

Je ne sais pas si cela a un effet sur la sérialisation ou non à ce stade

1
João Antunes

voir les réponses ci-dessus mais pour ajouter-- si vous ne vouliez que la sortie lorsque la valeur n'est pas nulle (par exemple XML maxOccurs = 0), vous pouvez utiliser quelque chose comme ceci:

private System.DateTime? someDateField;

public string someDate
{
    get
    {
        return someDateField?.ToString("MM-dd-yyyy");
    }
    set
    {
        dobField = System.DateTime.Parse(value);
    }
}
1
Brian