web-dev-qa-db-fra.com

Spécification d'un format DateTime personnalisé lors de la sérialisation avec Json.Net

Je développe une API pour exposer certaines données à l'aide de l'API Web ASP.NET.

Dans l'une des API, le client souhaite que nous exposions la date au format yyyy-MM-dd. Je ne souhaite pas modifier les paramètres globaux (par exemple, GlobalConfiguration.Configuration.Formatters.JsonFormatter), car ils sont très spécifiques à ce client. Et je développe cela dans une solution pour plusieurs clients.

Une des solutions à laquelle je pouvais penser est de créer un JsonConverter personnalisé, puis de le mettre dans la propriété dont j'ai besoin pour effectuer le formatage personnalisé.

par exemple.

class ReturnObjectA 
{
    [JsonConverter(typeof(CustomDateTimeConverter))]
    public DateTime ReturnDate { get;set;}
}

Je me demandais simplement s'il y avait un autre moyen facile de le faire.

107
Stay Foolish

Tu es sur la bonne piste. Puisque vous avez dit que vous ne pouviez pas modifier les paramètres globaux, la meilleure chose à faire est d'appliquer l'attribut JsonConverter au besoin, comme vous l'avez suggéré. Il s'avère que Json.Net a déjà une fonction intégrée IsoDateTimeConverter qui vous permet de spécifier le format de date. Malheureusement, vous ne pouvez pas définir le format via l'attribut JsonConverter, car l'unique argument de l'attribut est un type. Cependant, il existe une solution simple: sous-classe IsoDateTimeConverter, puis spécifiez le format de date dans le constructeur de la sous-classe. Appliquez l'attribut JsonConverter si nécessaire, en spécifiant votre convertisseur personnalisé, et le tour est joué. Voici l'intégralité du code nécessaire:

class CustomDateTimeConverter : IsoDateTimeConverter
{
    public CustomDateTimeConverter()
    {
        base.DateTimeFormat = "yyyy-MM-dd";
    }
}

Si le temps vous y intéresse également, vous n'avez même pas besoin de sous-classer IsoDateTimeConverter. Son format de date par défaut est yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK (comme indiqué dans le code source ).

136
Brian Rogers

Vous pouvez utiliser cette approche:

public class DateFormatConverter : IsoDateTimeConverter
{
    public DateFormatConverter(string format)
    {
        DateTimeFormat = format;
    }
}

Et utilisez-le de cette façon:

class ReturnObjectA 
{
    [JsonConverter(typeof(DateFormatConverter), "yyyy-MM-dd")]
    public DateTime ReturnDate { get;set;}
}

La chaîne DateTimeFormat utilise la syntaxe de chaîne de format .NET décrite ici: https://docs.Microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings

68
Keith Hill

Cela peut également être fait avec une instance IsoDateTimeConverter, sans changer les paramètres de formatage globaux:

string json = JsonConvert.SerializeObject(yourObject,
    new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" });

Ceci utilise la surcharge JsonConvert.SerializeObject qui prend un argument params JsonConverter[].

43
Saeb Amini

Egalement disponible en utilisant l’une des surcharges de paramètres du sérialiseur:

var json = JsonConvert.SerializeObject(someObject, new JsonSerializerSettings() { DateFormatString = "yyyy-MM-ddThh:mm:ssZ" });

Ou

var json = JsonConvert.SerializeObject(someObject, Formatting.Indented, new JsonSerializerSettings() { DateFormatString = "yyyy-MM-ddThh:mm:ssZ" });

Les surcharges prenant un type sont également disponibles.

12
Matt

Construire une classe d'assistance et l'appliquer à votre attribut de propriété

Classe d'assistance:

public class ESDateTimeConverter : IsoDateTimeConverter
{
    public ESDateTimeConverter()
    {
        base.DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffZ";
    }
}

Votre code utilise comme ceci:

[JsonConverter(typeof(ESDateTimeConverter))]
public DateTime timestamp { get; set; }
4
Xin

Quelques fois décorer l'attribut json convert ne fonctionnera pas, il sera par exception en disant que " 2010-10-01" est une date valide . Pour éviter cela, j'ai supprimé l'attribut json convert de la propriété et mentionné dans la méthode deserilizedObject comme ci-dessous.

var addresss = JsonConvert.DeserializeObject<AddressHistory>(address, new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd" });
0
Muni Chittem

Il y a une autre solution que j'utilise. Créez simplement une propriété de chaîne et utilisez-la pour json. Cette propriété retournera la date correctement formatée.

class JSonModel {
    ...

    [JsonProperty("date")]
    public string MyDate { get; set; }

    public string CustomDate {
        get { return MyDate.ToString("DDMMYY"); }
        set { MyDate = DateTime.Parse(value); }
    }

    ...
}

De cette façon, vous n'avez pas à créer de classes supplémentaires. En outre, il vous permet de créer différents formats de données. Par exemple, vous pouvez facilement créer une autre propriété pour Hour en utilisant le même DateTime.

0