Сериализация нескольких свойств DateTime в одном классе с использованием разных форматов для каждого из них
У меня есть класс с двумя свойствами DateTime. Мне нужно сериализовать каждое из свойств с другим форматом. Как мне это сделать? Я пробовал:
JsonConvert.SerializeObject(obj, Formatting.None,
new IsoDateTimeConverter {DateTimeFormat = "MM.dd.yyyy"});
Это решение не работает для меня, потому что оно применяет формат даты ко всем свойствам. Есть ли способ сериализации каждого свойства DateTime в другом формате? Может быть, есть какой-то атрибут?
Ответы
Ответ 1
NewtonSoft.Json
имеет структуру, которую трудно понять, вы можете использовать что-то вроде следующего настраиваемого конвертера, чтобы делать то, что вы хотите:
[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();
}
}
Ответ 2
Простым способом справиться с этой ситуацией является подкласс IsoDateTimeConverter
для создания настраиваемого конвертера дат для каждого формата даты, который вам нужен. Например:
class MonthDayYearDateConverter : IsoDateTimeConverter
{
public MonthDayYearDateConverter()
{
DateTimeFormat = "MM.dd.yyyy";
}
}
class LongDateConverter : IsoDateTimeConverter
{
public LongDateConverter()
{
DateTimeFormat = "MMMM dd, yyyy";
}
}
Затем вы можете использовать атрибут [JsonConverter]
для украшения отдельных свойств DateTime
в любых классах, которые нуждаются в специальном форматировании:
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; }
}
Демо:
Foo foo = new Foo
{
Date1 = DateTime.Now,
Date2 = DateTime.Now,
Date3 = DateTime.Now
};
string json = JsonConvert.SerializeObject(foo, Formatting.Indented);
Console.WriteLine(json);
Вывод:
{
"Date1": "03.03.2014",
"Date2": "March 03, 2014",
"Date3": "2014-03-03T10:25:49.8885852-06:00"
}
Ответ 3
Вы можете создать пользовательский класс даты, который наследует IsoDateTimeConverter и передает формат конструктору. В атрибутах вы можете указать, какой формат соответствует каждому свойству. См. Следующий код:
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;
}
}
Ответ 4
Я понимаю, что это старый вопрос, но я наткнулся на него во время поиска того же вопроса.
У Newtonsoft теперь есть свойство DateFormatString в классе JsonSerializerSettings, который вы можете использовать. Я пришел к этому вопросу, ища ответ и только что нашел свойство, я использовал его, как показано ниже, и он работает следующим образом:
private const string _StrDateFormat = "yyyy-MM-dd HH:mm:ss";
private static string GetJSON(object value)
{
return JsonConvert.SerializeObject(value, new JsonSerializerSettings
{
DateFormatString = _StrDateFormat
});
}
Когда value
будет иметь объект DateTime, он преобразует его в строку, соответствующую строке _StrDateFormat
.
Возможно, эта официальная ссылка может быть обновлена?
С уважением.