如何使用Joda.net使用NodaTime.Instant反序列化字典而不会出现异常?

Run*_*une 10 json.net nodatime

序列化一个字典,NodaTime.Instance使用json.net到JSON 工作正常,但在反序列化它抛出 Newtonsoft.Json.JsonSerializationException.下面的测试显示了问题:

[Test] 
public void DeserializeDictionaryThowsException() {
    JsonConverter[] converters = { NodaConverters.IntervalConverter, NodaConverters.InstantConverter };

    var dictionary = new Dictionary<Instant, int>() {
         {Instant.FromUtc(2012, 1, 2, 3, 4, 5), 0}
    };            
    var json = JsonConvert.SerializeObject(dictionary, Formatting.None, converters);
    Assert.AreEqual("{\"2012-01-02T03:04:05Z\":0}", json); //ok
    var result = JsonConvert.DeserializeObject<Dictionary<Instant, int>>(json, converters); // throws
}
Run Code Online (Sandbox Code Playgroud)

DeserializeObject抛出:

Newtonsoft.Json.JsonSerializationException:无法将字符串'2012-01-02T03:04:05Z'转换为字典键类型'NodaTime.Instant'.创建TypeConverter以将字符串转换为键类型对象.第1行,第24位.----> Newtonsoft.Json.JsonSerializationException:将值"2012-01-02T03:04:05Z"转换为'NodaTime.Instant'时出错.第1行,第24位.----> System.Exception:无法从System.String转换或转换为NodaTime.Instant.

作为旁注,反序列化DateTime字典可以正常工作.我猜因为String有一个DateTime转换器.

[Test]
public void DeserializeDiciotnaryOfDateTime() // OK
{
    var expected = new DateTime(2012, 1, 2, 3, 4, 5, DateTimeKind.Utc);
    var dictionary = new Dictionary<DateTime, int>() { { expected, 0 } };
    var json = JsonConvert.SerializeObject(dictionary);       
    var result = JsonConvert.DeserializeObject<Dictionary<DateTime, int>>(json); 
    Assert.AreEqual(expected, dictionary.Keys.First()); // OK
}
Run Code Online (Sandbox Code Playgroud)

小智 1

您需要添加更多 JSON.NET 转换器来序列化 NodaTime.Instance 时间,如下所示。

public void DeserializeDictionaryThowsException()
{
    var dtzProvider = DateTimeZoneCache.GetSystemDefault();
    JsonConverter[] converters = { NodaConverters.IntervalConverter, 
                                   NodaConverters.InstantConverter,
                                   NodaConverters.LocalDateConverter,
                                   NodaConverters.LocalDateTimeConverter,
                                   NodaConverters.LocalTimeConverter,
                                   NodaConverters.OffsetConverter,
                                   NodaConverters.DurationConverter,
                                   NodaConverters.RoundtripPeriodConverter,
                                   NodaConverters.OffsetDateTimeConverter,
                                   NodaConverters.CreateDateTimeZoneConverter(dtzProvider),
                                   NodaConverters.CreateZonedDateTimeConverter(dtzProvider)
                                 };

    var dictionary = new Dictionary<Instant, int>() { { Instant.FromUtc(2012, 1, 2, 3, 4, 5), 0 } };
    var json = JsonConvert.SerializeObject(dictionary, Formatting.None, converters);
    Assert.AreEqual("{\"2012-01-02T03:04:05Z\":0}", json);
    var result = JsonConvert.DeserializeObject<Dictionary<Instant, int>>(json, converters);
}
Run Code Online (Sandbox Code Playgroud)