57 votes

Pourquoi DateTime.MinValue ne peut pas être sérialisé dans les fuseaux horaires en avance sur l'UTC ?

Je rencontre des problèmes avec un service WCF REST. Certaines propriétés de l'objet filaire que j'essaie de renvoyer ne sont pas définies, ce qui se traduit par DateTime.MinValue pour les propriétés de type DateTime. Le service renvoie un document vide (avec le statut HTTP 200 ? ??). Lorsque j'essaie d'appeler moi-même la sérialisation JSON, l'exception qui est levée est la suivante :

SerializationException : Les valeurs DateTime qui sont supérieures à DateTime.MaxValue ou inférieures à DateTime.MinValue lorsqu'elles sont converties en UTC ne peuvent pas être sérialisées en JSON.

Ce problème peut être reproduit en exécutant le code suivant dans une application console :

DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(DateTime));
MemoryStream m = new MemoryStream();
DateTime dt = DateTime.MinValue;

// throws SerializationException in my timezone
ser.WriteObject(m, dt);
string json = Encoding.ASCII.GetString(m.GetBuffer());
Console.WriteLine(json);

Pourquoi ce comportement ? Je pense que c'est lié à mon fuseau horaire (GMT+1). Comme DateTime.MinValue est default(DateTime), je m'attendrais à ce que cela puisse être sérialisé sans problème.

Des conseils pour que mon service REST se comporte bien ? Je ne veux pas modifier mon DataContract.

0 votes

Pouvez-vous rendre votre DateTime nullable et utiliser null comme valeur par défaut ?

0 votes

@Gabe : Je suppose que je pourrais. Cela semble stupide de changer mon type pour contourner un détail de sérialisation. Mais c'est probablement la voie la plus pragmatique.

0voto

Sebastian Points 454

Vous pouvez corriger cela pendant la sérialisation via l'option OnSerializing et un peu de réflexion :

[OnSerializing]
public void OnSerializing(StreamingContext context)
{
  var properties = this.GetType().GetProperties();
  foreach (PropertyInfo property in properties)
  {
    if (property.PropertyType == typeof(DateTime) && property.GetValue(this).Equals(DateTime.MinValue))
    {
      property.SetValue(this, DateTime.MinValue.ToUniversalTime());
    }
  }
}

0voto

Tal Aloni Points 11

Il est possible d'éviter ce problème (avec la méthode WriteDateTimeInDefaultFormat) en spécifiant un DateTimeFormat personnalisé :

DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings();
settings.DateTimeFormat = new DateTimeFormat("yyyy-MM-ddThh:mm:ss.fffZ");
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(MyDataContract), settings);

Notez que vous devez vous assurer que la valeur DateTime est réellement en UTC, mais vous pouvez l'utiliser en toute sécurité avec DateTime.MinValue.

Voir este pour plus de détails sur le format DateTimeFormat utilisé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X