Указание пользовательского формата DateTime при сериализации с помощью Json.Net
Я разрабатываю API для публикации некоторых данных с помощью ASP.NET Web API.
В одном из API клиент хочет, чтобы мы отображали дату в формате yyyy-MM-dd
. Я не хочу изменять глобальные настройки (например, GlobalConfiguration.Configuration.Formatters.JsonFormatter
) для этого, поскольку он очень специфичен для этого клиента. И я развиваю это в решении для нескольких клиентов.
Одним из решений, о котором я мог подумать, является создание пользовательского JsonConverter
а затем JsonConverter
его в свойство, которое мне нужно для создания пользовательского форматирования
например
class ReturnObjectA
{
[JsonConverter(typeof(CustomDateTimeConverter))]
public DateTime ReturnDate { get;set;}
}
Просто интересно, есть ли другой простой способ сделать это.
Ответы
Ответ 1
Вы на правильном пути. Поскольку вы сказали, что не можете изменять глобальные параметры, то лучше всего применять атрибут JsonConverter
по мере необходимости, как вы предложили. Оказывается, у Json.Net уже есть встроенный IsoDateTimeConverter
, который позволяет указать формат даты. К сожалению, вы не можете установить формат с помощью атрибута JsonConverter
, так как единственным аргументом атрибута является тип. Однако существует простое решение: подкласс IsoDateTimeConverter
, затем укажите формат даты в конструкторе подкласса. Примените атрибут JsonConverter
, где необходимо, указав свой собственный конвертер, и вы готовы к работе. Вот полный код необходимого кода:
class CustomDateTimeConverter : IsoDateTimeConverter
{
public CustomDateTimeConverter()
{
base.DateTimeFormat = "yyyy-MM-dd";
}
}
Если вы не против иметь время там, вам даже не нужно подклассифицировать IsoDateTimeConverter. Формат даты по умолчанию - yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK
(как показано в исходный код).
Ответ 2
Вы можете использовать этот подход:
public class DateFormatConverter : IsoDateTimeConverter
{
public DateFormatConverter(string format)
{
DateTimeFormat = format;
}
}
И используйте его так:
class ReturnObjectA
{
[JsonConverter(typeof(DateFormatConverter), "yyyy-MM-dd")]
public DateTime ReturnDate { get;set;}
}
Строка DateTimeFormat использует синтаксис строки формата .NET, описанный здесь: https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings
Ответ 3
Это также можно сделать с помощью экземпляра IsoDateTimeConverter
без изменения глобальных настроек форматирования:
string json = JsonConvert.SerializeObject(yourObject,
new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" });
При этом используется перегрузка JsonConvert.SerializeObject
которая принимает аргумент params JsonConverter[]
.
Ответ 4
Также можно использовать одну из настроек перегрузки параметров сериализатора:
var json = JsonConvert.SerializeObject(someObject, new JsonSerializerSettings() { DateFormatString = "yyyy-MM-ddThh:mm:ssZ" });
или
var json = JsonConvert.SerializeObject(someObject, Formatting.Indented, new JsonSerializerSettings() { DateFormatString = "yyyy-MM-ddThh:mm:ssZ" });
Также доступны перегрузки с типом.
Ответ 5
Создайте вспомогательный класс и примените его к атрибуту свойства
Класс помощника:
public class ESDateTimeConverter : IsoDateTimeConverter
{
public ESDateTimeConverter()
{
base.DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffZ";
}
}
Ваш код используется следующим образом:
[JsonConverter(typeof(ESDateTimeConverter))]
public DateTime timestamp { get; set; }
Ответ 6
Есть еще одно решение, которое я использовал. Просто создайте строковое свойство и используйте его для json. Это свойство вернет дату, правильно отформатированную.
class JSonModel {
...
private DateTime myDate;
[JsonProperty("date")]
public string CustomDate {
get { return myDate.ToString("DDMMYY"); }
set { myDate = DateTime.Parse(value); }
}
...
}
Таким образом, вам не нужно создавать дополнительные классы. Кроме того, он позволяет создавать разные форматы данных. Например, вы можете легко создать другое свойство для часа, используя тот же DateTime.
Ответ 7
Иногда декорирование атрибута json convert не будет работать, за исключением того, что " 2010-10-01" является допустимой датой. Чтобы избежать этого, я удалил атрибут json convert в свойстве и упомянул в методе deserilizedObject, как показано ниже.
var addresss = JsonConvert.DeserializeObject<AddressHistory>(address, new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd" });