2016-10-26 21 views
4

DateTimeフィールドをDateTime.MinValueに設定し、"0001-01-01T00:00:00"の代わりにNULLにシリアル化するWeb APIから返されるフィールドを指定します。JSON.NET DateTime.MinValueをnullとしてシリアル化

JSON.NETにデフォルト値に設定されているフィールドを省略させる方法があると私は理解していますが、具体的にはDateTime MinValue/"0001-01-01T00:00:00" as nullをシリアル化するのがJSON.NETよりも好きです。

これを行う方法はありますか?

+0

あなたはプロパティ自体に設定することができます。そのDateTime.MinValueの場合。あなたのDateTimeはnull可能であるはずです。 –

+0

おそらく間違いですが、NOT NULL DateTime列のエンティティコードを 'DateTime'として生成するコード生成システムがあります。列がNullableの場合、.NETタイプは 'DateTime?'です。私は多くのコードを壊すことなくこれを変更できるとは思わない – Mick

+0

null可能にすることなく、null値をDateTimeに割り当てることはできません –

答えて

6

(必要な場合)DateTime.MinValuenullをデシリアライズnullDateTime.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'を変更して 'DateTime'と' 'DateTime? ' – dbc

+0

@dbcこのコンバータは、' JsonConverter'属性を使って 'DateTime'プロパティに直接適用した場合にのみ機能します。 'CanConvert'はこのシナリオでは呼び出されません。 'DateTime?'型をサポートする必要がある場合、 'ReadJson'を修正する必要があります。 –

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" 
} 
関連する問題