Подтвердить что ты не робот

Указание пользовательского формата 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;}
}

Просто интересно, есть ли другой простой способ сделать это.

4b9b3361

Ответ 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" });