使用JSON.NET反序名化Noda Time的LocalDateTime

Mat*_*ine 9 c# datetime date json.net nodatime

我正在尝试使用Json.NET序列化一些Noda Time值并遇到麻烦.序列化很简单:

LocalDateTime dt = ... // Assigned elsewhere
LocalDateTimePattern isoDateTimePattern = LocalDateTimePattern.GeneralIsoPattern;
JObject root = new JObject();
root.Add("time", isoDateTimePattern.Format(dt));

// Serialize other elements

using (var sw = new StreamWriter(stream)) {
    serializer.Serialize(sw, root);
}
Run Code Online (Sandbox Code Playgroud)

但是反序列化是有问题的.Json.NET似乎从上面识别出ISO格式的日期和时间,并自动将其转换为DateTime对象,这不是我想要的.

using (var sr = new StreamReader(stream)) {
        using (var jr = new JsonTextReader(sr)) {
            var root = serializer.Deserialize<JObject>(jr);

            // Deserialize other elements

            var time = root.GetValue("time"); // time.Type is JTokenType.Date
            string timeStr = time.Value<string>(); // Is "01/10/2014 10:37:32"

            // Kaboom. String is not in the right format (see above comment)
            var parsedTime = isoDateTimePattern.Parse(time.Value<string>());
        }
}
Run Code Online (Sandbox Code Playgroud)

timeStr美国格式的日期和时间出来的事实来看,我猜想time.Value<string>() 只是调用Json.NET已经解析过的ToString一些内部DateTime对象.我可以做点什么

var cdt = time.Value<DateTime>();
LocalDateTime ldt = new LocalDateTime(cdt.Year, cdt.Month, cdt.Day, cdt.Hour, cdt.Minute);
Run Code Online (Sandbox Code Playgroud)

但这令人费解,意味着Json.NET正在执行不必要的转换.

有没有办法获得JSON值的原始字符串值?

Bri*_*ers 18

NuGet上有一个NodaTime.Serialization.JsonNet软件包,它似乎完全针对这种情况.以下是如何设置它:

在解决方案中下载并安装软件包后,将以下using语句添加到您的代码中:

using NodaTime.Serialization.JsonNet;
Run Code Online (Sandbox Code Playgroud)

像这样设置你的序列化器:

JsonSerializer serializer = new JsonSerializer();
serializer.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
Run Code Online (Sandbox Code Playgroud)

然后,当你反序列化时,你可以LocalDateTime从这样的JObject使用中得到一个ToObject<LocalDateTime>(serializer):

using (var sr = new StreamReader(stream))
{
    using (var jr = new JsonTextReader(sr))
    {
        var root = serializer.Deserialize<JObject>(jr);

        // Deserialize other elements

        var time = root.GetValue("time");
        var parsedTime = time.ToObject<LocalDateTime>(serializer);
    }
}
Run Code Online (Sandbox Code Playgroud)