J'ai une application Web API qui renvoie JSON aux consommateurs qui n'utilisent peut-être pas les technologies Microsoft. Lorsque mon contrôleur renvoie un objet avec les propriétés DateTime au format JSON, il sérialise la date dans ce format:
2017-03-15T00:00:00-04:00
Cela donne au consommateur un peu de mal de tête car ils s'attendent à ce qu'il soit au format ISO 8601. Certaines recherches m'ont dit que JSON.NET utilise désormais ISO 8601 par défaut (j'utilise 9.0.1). Quand j'exécute ce code ...
Clipboard.Copy(JsonConvert.SerializeObject(DateTime.Now));
...J'ai compris:
2017-03-15T09:10:13.8105498-04:00
Wikipedia les présente comme des formats ISO 8601 valides lors de l'expression de la date et de l'heure complètes:
2017-03-15T11:45:42+00:00
2017-03-15T11:45:42Z
20170315T114542Z
Cependant, la sortie que j'ai obtenue ci-dessus ne correspond exactement à aucun de ceux-ci. Je veux que le formateur utilise 2017-03-15T11:45:42Z
.
Et probablement digne d'une autre question, l'ajout de la ligne ci-dessous dans ma configuration d'API Web semble être ignoré car il continue de renvoyer JSON à la date indiquée ci-dessus:
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new IsoDateTimeConverter());
Je suppose qu'une fois que j'ai compris le problème principal, le problème de l'API Web peut également être résolu.
Le format que vous obtenez est format ISO 8601 (lisez la section sur les désignateurs d'heure et de fuseau horaire dans Wikipedia), c'est juste que vos dates ne sont apparemment pas ajustées à l'heure UTC, donc vous obtenez un décalage de fuseau horaire ajouté à la date plutôt qu'à l'indicateur de fuseau horaire Z
Zulu.
IsoDateTimeConverter
possède des paramètres que vous pouvez utiliser pour personnaliser sa sortie. Vous pouvez le faire ajuster automatiquement les dates en UTC en définissant DateTimeStyles
sur AdjustToUniversal
. Vous pouvez également personnaliser le format de sortie pour omettre les fractions de seconde si vous ne les souhaitez pas. Par défaut, le convertisseur ne s'ajuste pas à l'heure UTC et inclut autant de décimales de précision qu'il y en a pour les secondes.
Essaye ça:
IsoDateTimeConverter converter = new IsoDateTimeConverter
{
DateTimeStyles = DateTimeStyles.AdjustToUniversal,
DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ssK"
};
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(converter);
Si vos dates sont déjà UTC, mais que le DateTimeKind
sur celles-ci n'est pas défini sur Utc
comme il devrait l'être (par exemple, c'est Unspecified
), alors idéalement, vous devriez corriger votre code afin que cet indicateur soit correctement défini avant la sérialisation. Cependant, si vous ne pouvez pas (ou ne voulez pas) le faire, vous pouvez contourner ce problème en modifiant les paramètres du convertisseur pour toujours inclure l'indicateur Z
dans le format de date (au lieu d'utiliser le K
spécificateur qui regarde le DateTimeKind
à la date) et en supprimant la directive AdjustToUniversal
.
IsoDateTimeConverter converter = new IsoDateTimeConverter
{
DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"
};
Ajout à la réponse de @Brian Rogers, pour ASP Core, ajoutez Startup.cs
:
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddJsonOptions(options =>
options.SerializerSettings.Converters.Add(new IsoDateTimeConverter
{
DateTimeStyles = DateTimeStyles.AdjustToUniversal
}));