ServiceStack – Existe-t-il un moyen de forcer toutes les dates sérialisées à utiliser un DateTimeKind spécifique?

J’ai un POCO comme ça:

public class BlogEntry { public ssortingng Title { get; set; } public DateTime Date { get; set; } } 

La plupart du temps, il est hydraté à partir de Entity Framework, mais il peut et sera utilisé en dehors de Entity Framework.

Le DateTimeKind pour la date de EF est non spécifié, ce qui, d’après ce que j’ai lu, est normal.

Lorsque je cache ce POCO dans Redis (à l’aide du client ServiceStack Redis), il revient avec un DateTimeKind of Local.

Donc, il y a une gigue avec les objects retournés. La première passe (non mise en cache) correspond à ISO-8061 sans décalage (DateTimeKind.Unspecified). La deuxième passe (mise en cache) est ISO-8061 avec un décalage (de Redis avec DateTimeKind.Local).

Un moyen de forcer le sérialiseur JSON ServiceStack à toujours interpréter les dates comme un DateTimeKind donné? (Je sais qu’il existe une propriété “JsConfig.AppendUtcOffset”, mais que ce soit vrai ou faux, les valeurs ne changent jamais pour moi?)

Ou quelque part dans le processus de désérialisation de mon RedisClient typé pour rendre le DateTimeKind local?

Je peux modifier manuellement mes POCO pour appliquer le DateTimeKind – et cela fonctionne – mais j’espérais quelque chose de moins sujet aux erreurs.

Si vous avez besoin de quelque chose de plus configurable que la réponse de @ mythz, vous pouvez forcer la sérialisation ou la désérialisation de DateTimes pour avoir un certain DateTimeKind en remplaçant DateTime et éventuellement DateTime? méthodes de sérialisation et / ou de désérialisation.

Forcer tous les DateTimes sérialisés à être interprétés comme UTC

 JsConfig.SerializeFn = time => new DateTime(time.Ticks, DateTimeKind.Local).ToSsortingng(); 

Vous pouvez ensuite aller plus loin et faire une erreur lors de la désérialisation si le format DateTime n’est pas spécifié. J’ai commencé à utiliser cela lorsque je voulais forcer les clients à spécifier le fuseau horaire dans toutes les demandes, mais ne nécessitais pas nécessairement que ce soit toujours Utc.

 JsConfig.DeSerializeFn = time => { if (!IsInCorrectDateFormat(time)) throw new System.Runtime.Serialization.SerializationException(BadDateTime); return ServiceStack.Text.Common.DateTimeSerializer.ParseDateTime(time); }; 

Le décalage DateTimeKind n’étant pas stocké avec Date, les sérialiseurs ServiceStack par défaut supposent que la date est locale, qu’elle est sérialisée au format UTC et désérialisée en tant que Local.

Vous pouvez obtenir que DateTimeKind.Unspecified soit assumé au format UTC avec:

 JsConfig.AssumeUtc = true; 

Un tweak à la solution bpruitt-goddard. Tout le mérite lui revient.

 JsConfig.SerializeFn = time => new DateTime(time.Ticks, DateTimeKind.Local).ToSsortingng("o"); JsConfig.SerializeFn = time => time != null ? new DateTime(time.Value.Ticks, DateTimeKind.Local).ToSsortingng("o") : null; JsConfig.DateHandler = DateHandler.ISO8601; 

Ainsi, toutes les dates sortant de la stack de services seront forcées dans un format de date ISO8601 et toutes les dates entrant seront automatiquement converties en date C # à partir de la chaîne ISO8601.