2013-07-25 9 views
14

Mam klasę z dwiema właściwościami DateTime. Muszę serializować każdą z właściwości w innym formacie. Jak mogę to zrobić? Próbowałem:Serializowanie wielu właściwości DateTime w tej samej klasie przy użyciu różnych formatów dla każdej z nich.

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

To rozwiązanie nie działa, ponieważ stosuje format daty do wszystkich właściwości. Czy istnieje sposób serializacji każdej właściwości DateTime w innym formacie? Może jest jakiś atrybut?

Odpowiedz

7

NewtonSoft.Json posiada strukturę, która jest trochę trudne do zrozumienia, można użyć coś jak na poniższym niestandardowy konwerter robić to, co chcesz:

[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(); 
    } 
} 
+0

Dzięki. Jest to pomocne – Andrei

29

prosty sposób obsługiwać tej sytuacji jest podklasy IsoDateTimeConverter do utwórz niestandardowy konwerter dat dla każdego wymaganego formatu daty. Na przykład:

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

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

Następnie można użyć atrybutu [JsonConverter] ozdobić poszczególne DateTime właściwości w każdych zajęć, które wymagają niestandardowego formatowania:

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; } 
} 

Demo:

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

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

wyjściowy:

{ 
    "Date1": "03.03.2014", 
    "Date2": "March 03, 2014", 
    "Date3": "2014-03-03T10:25:49.8885852-06:00" 
} 
6

Możesz utworzyć niestandardową klasę daty, która dziedziczy IsoDateTimeConverter i przekazuje format do konstruktora. W atrybutach można określić, który format odpowiada każdej właściwości. Zobacz kod poniżej:

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; 
    } 
} 
1

Zdaję sobie sprawę, że jest to stare pytanie, ale natknąłem się na to podczas poszukiwania tego samego pytania.

Newtonsoft ma teraz DateFormatString nieruchomość w JsonSerializerSettings klasowych, które można użyć. Ja przyszedłem na to pytanie szuka odpowiedzi i właśnie okazało się, że nieruchomość, użyłem go jak poniżej i działa jak poniżej:

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

    private static string GetJSON(object value) 
    { 

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

Kiedy value będzie miał obiekt DateTime, będzie przekształcić go w ciąg poszanowaniem _StrDateFormat strunowy.

Być może this official link może być aktualizowany?

Pozdrawiam.

+1

Chociaż prawdą jest, że to ustawienie może być używane do zmiany formatu daty globalnie na szeregowanie, nie rozwiązuje problemu w pytaniu: jak serializować obiekt zawierający dwie daty i czy każda data ma inny format. –

Powiązane problemy