2016-10-26 2 views
4

Я хотел бы DateTime поля, которые установлены в DateTime.MinValue, возвращенные моим веб-API, для сериализации в NULL вместо "0001-01-01T00:00:00".JSON.NET Сериализовать DateTime.MinValue как null

Я понимаю, что есть способ заставить JSON.NET опускать поля, для которых установлены значения по умолчанию, но я бы предпочел, чтобы JSON.NET специально сериализовал DateTime MinValue/"0001-01-01T00:00:00" as null.

Есть ли способ сделать это?

+0

вы можете установить в самой собственности. если его DateTime.MinValue. Помните, что значение DateTime должно быть равно NULL. –

+0

Это, наверное, ошибка, но у нас есть система генерации кода, которая генерирует код сущности для столбцов NOT NULL DateTime как «DateTime». Если столбец Nullable, тип .NET является «DateTime?». Я не думаю, что могу изменить это, не нарушая много кода – Mick

+0

Но, не делая его ничтожным, вы не можете назначить значение null DateTime –

ответ

6

Создание пользовательского конвертер, который сериализующий DateTime.MinValue в null, и (при необходимости) десериализует null в DateTime.MinValue:

public class MinDateTimeConverter : DateTimeConverterBase 
{ 
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (reader.Value == null) 
      return DateTime.MinValue; 

     return (DateTime)reader.Value; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     DateTime dateTimeValue = (DateTime)value; 
     if (dateTimeValue == DateTime.MinValue) 
     { 
      writer.WriteNull(); 
      return; 
     } 

     writer.WriteValue(value); 
    } 
} 

Вы можете использовать атрибуты, чтобы добавить конвертер к классу данных, как показано в этом примере :

public class Example 
{ 
    [JsonConverter(typeof(MinDateTimeConverter))] 
    public DateTime ValueOne { get; set; } 

    [JsonConverter(typeof(MinDateTimeConverter))] 
    public DateTime ValueTwo { get; set; } 
} 

public static void Main(string[] args) 
{ 
    Example data = new Example(); 
    data.ValueOne = DateTime.MinValue; 
    data.ValueTwo = DateTime.Now; 

    JsonSerializer serializer = new JsonSerializer(); 

    using (StringWriter writer = new StringWriter()) 
    { 
     serializer.Serialize(writer, data); 
     Console.Write(writer.ToString()); 
    } 

    Console.ReadKey(); 
} 

Консоль вывода:

{"ValueOne":null,"ValueTwo":"2016-10-26T09:54:48.497463+01:00"} 
+0

['DateTimeConverterBase'] (https: //github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs) также принимает 'DateTimeOffset', поэтому вам нужно изменить' CanConvert', чтобы возвращать true только для 'DateTime' и 'DateTime?' – dbc

+0

@dbc Этот конвертор будет работать только при непосредственном применении к свойствам 'DateTime' с использованием атрибута' JsonConverter'. 'CanConvert' не вызывается в этом сценарии. 'ReadJson' нужно будет изменить, если необходимо поддерживать типы DateTime?'. –

4

Пользовательские DateTime Json конвертер

public class DateTimeConverter : JsonConverter 
{ 
    public override void WriteJson(JsonWriter jsonWriter, object inputObject,JsonSerializer jsonSerializer) 
    { 
     // Typecast the input object 
     var dateTimeObject = inputObject as DateTime?; 

     // Set the properties of the Json Writer 
     jsonWriter.Formatting = Newtonsoft.Json.Formatting.Indented; 

     if(dateTimeObject == DateTime.MinValue) 
      jsonWriter.WriteValue((DateTime?)null); 
     else 
      jsonWriter.WriteValue(dateTimeObject); 
    } 


    public override object ReadJson(JsonReader reader, 
     Type objectType, 
     object existingValue, 
     JsonSerializer serializer) 
    { 
     DateTime? readValue = reader.ReadAsDateTime(); 

     return (readValue == null) ? DateTime.MinValue : readValue;  

    } 


    public override bool CanConvert(Type objectType) 
    { 
     return typeof(DateTime?).IsAssignableFrom(objectType); 
    } 
} 

Использование:

public class DateTest 
{ 
    [JsonConverterAttribute(typeof(DateTimeConverter))] 
    public DateTime? MyDateTime { get; set;} 

    [JsonConverterAttribute(typeof(DateTimeConverter))] 
    public DateTime? MyDateTime1 { get; set; } 
} 

void Main() 
{ 
    DateTest dateTest = new DateTest 
    { 
     MyDateTime = DateTime.MinValue, 
     MyDateTime1 = DateTime.MaxValue 
    }; 

    Console.WriteLine(JsonConvert.SerializeObject(dateTest)); 
} 

Результат:

{ 
    "MyDateTime": null, 
    "MyDateTime1": "9999-12-31T23:59:59.9999999" 
}