Sérialiser plusieurs propriétés DateTime dans la même classe en utilisant des formats différents pour chacun

j'ai une classe avec deux propriétés DateTime. Je dois sérialiser chacune des propriétés avec un format différent. Comment puis-je le faire? J'ai essayé:

JsonConvert.SerializeObject(obj, Formatting.None,
      new IsoDateTimeConverter {DateTimeFormat = "MM.dd.yyyy"});

Cette solution ne fonctionne pas pour moi car elle applique le format date à toutes les propriétés. Y a-t-il un moyen de sérialiser chaque propriété DateTime avec un format différent? Peut-être qu'il est un attribut?

14
demandé sur Brian Rogers 2013-07-25 15:21:52

4 réponses

NewtonSoft.Json a une structure qui est un peu difficile à comprendre, vous pouvez utiliser quelque chose comme le convertisseur personnalisé suivant pour faire ce que vous voulez:

[TestMethod]
public void Conversion()
{
    var obj = new DualDate()
    {
        DateOne = new DateTime(2013, 07, 25),
        DateTwo = new DateTime(2013, 07, 25)
    };
    Assert.AreEqual("{\"DateOne\":\"07.25.2013\",\"DateTwo\":\"2013-07-25T00:00:00\"}", 
        JsonConvert.SerializeObject(obj, Formatting.None, new DualDateJsonConverter()));
}

class DualDate
{
    public DateTime DateOne { get; set; }
    public DateTime DateTwo { get; set; }
}

class DualDateJsonConverter : JsonConverter
{

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {

        JObject result = new JObject();

        DualDate dd = (DualDate)value;

        result.Add("DateOne", JToken.FromObject(dd.DateOne.ToString("MM.dd.yyyy")));
        result.Add("DateTwo", JToken.FromObject(dd.DateTwo));
        result.WriteTo(writer);
    }

    // Other JsonConverterMethods
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DualDate);
    }

    public override bool CanWrite
    {
        get
        {
            return true;
        }
    }
    public override bool CanRead
    {
        get
        {
            return false;
        }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
7
répondu paolobueno 2013-07-25 14:02:48

un moyen simple de gérer cette situation est de sous-classe le IsoDateTimeConverter pour créer un convertisseur de date personnalisé pour chaque format de date différent dont vous avez besoin. Par exemple:

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

class LongDateConverter : IsoDateTimeConverter
{
    public LongDateConverter()
    {
        DateTimeFormat = "MMMM dd, yyyy";
    }
}

alors vous pouvez utiliser l'attribut [JsonConverter] pour décorer les propriétés individuelles DateTime dans toutes les classes qui ont besoin de formatage personnalisé:

class Foo
{
    [JsonConverter(typeof(MonthDayYearDateConverter))]
    public DateTime Date1 { get; set; }

    [JsonConverter(typeof(LongDateConverter))]
    public DateTime Date2 { get; set; }

    // Use default formatting
    public DateTime Date3 { get; set; }
}

Démo:

Foo foo = new Foo
{
    Date1 = DateTime.Now,
    Date2 = DateTime.Now,
    Date3 = DateTime.Now
};

string json = JsonConvert.SerializeObject(foo, Formatting.Indented);
Console.WriteLine(json);

sortie:

{
  "Date1": "03.03.2014",
  "Date2": "March 03, 2014",
  "Date3": "2014-03-03T10:25:49.8885852-06:00"
}
29
répondu Brian Rogers 2014-03-03 16:37:30

vous pouvez créer une classe de date personnalisée qui hérite de L'IsoDateTimeConverter et passer un format sur le constructeur. Sur les attributs, vous pouvez spécifier le format correspond à chaque propriété. Voir code ci-dessous:

public class LoginResponse
{
    [JsonProperty("access_token")]
    public string AccessToken { get; set; }
    [JsonProperty("token_type")]
    public string TokenType { get; set; }
    [JsonProperty("expires_in")]
    public DateTime ExpiresIn { get; set; }
    [JsonProperty("userName")]
    public string Username { get; set; }
    [JsonConverter(typeof(CustomDateFormat), "EEE, dd MMM yyyy HH:mm:ss zzz")]
    [JsonProperty(".issued")]
    public DateTime Issued { get; set; }
    [JsonConverter(typeof(CustomDateFormat), "MMMM dd, yyyy")]
    [JsonProperty(".expires")]
    public DateTime Expires { get; set; }
}

public class CustomDateFormat : IsoDateTimeConverter
{
    public CustomDateFormat(string format)
    {
        DateTimeFormat = format;
    }
}
7
répondu jeiem 2016-03-17 08:22:13

je me rends compte que c'est une vieille question, mais je suis tombé dessus pendant ma recherche pour la même question.

Newtonsoft a maintenant une DateFormatString propriété dans jsonserializersettings classe que vous pouvez utiliser. Je suis venu à cette question à la recherche de réponse et je viens de trouver la propriété, je l'ai utilisé comme ci-dessous et il fonctionne comme ci-dessous:

    private const string _StrDateFormat = "yyyy-MM-dd HH:mm:ss";

    private static string GetJSON(object value)
    {

        return JsonConvert.SerializeObject(value, new JsonSerializerSettings
        {
            DateFormatString = _StrDateFormat
        });
    }

quand value aura une DateTime objet, il le convertira en chaîne de caractères respectant la chaîne _StrDateFormat .

peut-être ce lien officiel peut-il être mis à jour?

Cordialement.

1
répondu Fwd079 2016-03-31 10:15:34