Указание пользовательского формата DateTime при сериализации с помощью Json.Net
Я разрабатываю API для публикации некоторых данных с помощью ASP.NET Web API.
В одном из API клиент хочет, чтобы мы отображали дату в формате yyyy-MM-dd
. Я не хочу изменять глобальные настройки (например, GlobalConfiguration.Configuration.Formatters.JsonFormatter
) для этого, поскольку он очень специфичен для этого клиента. И я развиваю это в решении для нескольких клиентов.
Одним из решений, о котором я мог подумать, является создание пользовательского JsonConverter
а затем JsonConverter
его в свойство, которое мне нужно для создания пользовательского форматирования
- Разбор большого json-файла в .NET.
- Deserializing JSON, когда иногда массивы, а иногда и объекты
- Как десериализовать данные JSON?
- Сериализация типа Json.Net с полиморфным дочерним объектом
- Как вернуть объект JSon
например
class ReturnObjectA { [JsonConverter(typeof(CustomDateTimeConverter))] public DateTime ReturnDate { get;set;} }
Просто интересно, есть ли другой простой способ сделать это.
- Как преобразовать массив Json в список объектов в c #
- JsonValueProviderFactory выбрасывает «запрос слишком большой»
- Как игнорировать неизвестные значения enum во время десериализации json?
- Разбор JSON DateTime от JSON Serializer от Newtonsoft
- Как преобразовать datatable в строку json с помощью json.net?
- JSON.NET - как десериализовать сборку интерфейсных экземпляров?
- Как использовать JSON.NET для десериализации в вложенный / рекурсивный словарь и список?
- C # JSON.NET - десериализация ответа, использующего необычную структуру данных
Ты на правильном пути. Поскольку вы сказали, что не можете изменять глобальные настройки, то лучше всего применить атрибут JsonConverter
по мере необходимости, как вы предложили. Оказывается, Json.Net уже имеет встроенный IsoDateTimeConverter
который позволяет указать формат даты. К сожалению, вы не можете установить формат с помощью атрибута JsonConverter
, поскольку единственным аргументом атрибута является тип. Однако существует простое решение: подclass IsoDateTimeConverter
, затем укажите формат даты в конструкторе подclassа. Примените атрибут JsonConverter
где необходимо, указав свой собственный конвертер, и вы готовы к работе. Вот полный код необходимого кода:
class CustomDateTimeConverter : IsoDateTimeConverter { public CustomDateTimeConverter() { base.DateTimeFormat = "yyyy-MM-dd"; } }
Если вы не возражаете, чтобы там было время, вам даже не нужно подclassифицировать IsoDateTimeConverter. Его формат даты по умолчанию – yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK
(как видно из исходного кода ).
Это также можно сделать с помощью экземпляра temp IsoDateTimeConverter
без изменения настроек глобального форматирования:
string json = JsonConvert.SerializeObject(yourObject, new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" });
Это использует перегрузку, которая принимает params JsonConverter[]
.
Вы можете использовать этот подход:
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
Также можно использовать одну из настроек переустановки сериализатора:
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" });
Также доступны перегрузки с типом.
Создайте вспомогательный class и примените его к атрибуту свойства
Класс помощника:
public class ESDateTimeConverter : IsoDateTimeConverter { public ESDateTimeConverter() { base.DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffZ"; } }
Ваш код используется следующим образом:
[JsonConverter(typeof(ESDateTimeConverter))] public DateTime timestamp { get; set; }