【问题标题】:Deserializing Noda Time's LocalDateTime with JSON.NET使用 JSON.NET 反序列化 Noda Time 的 LocalDateTime
【发布时间】:2014-01-29 18:16:58
【问题描述】:

我正在尝试使用 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);
}

但是反序列化是有问题的。 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>());
        }
}

timeStr 以美国格式日期和时间出现的事实来看,我猜time.Value&lt;string&gt;() 只需在 Json.NET 已经解析的一些内部 DateTime 对象上调用 ToString。 我可以做类似的事情

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

但这很复杂,意味着 Json.NET 正在执行不需要的转换。

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

【问题讨论】:

    标签: c# date datetime json.net nodatime


    【解决方案1】:

    NuGet 上有一个NodaTime.Serialization.JsonNet package 可用,似乎正是针对这种情况。设置方法如下:

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

    using NodaTime.Serialization.JsonNet;
    

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

    JsonSerializer serializer = new JsonSerializer();
    serializer.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
    

    然后,当您反序列化时,您可以像这样使用ToObject&lt;LocalDateTime&gt;(serializer)JObject 获得LocalDateTime

    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);
        }
    }
    

    【讨论】:

    • 同样,你将如何序列化?从您的示例中,您似乎会使用以下内容,但它失败并出现错误“测试方法 LiveSerialTests.LinkTests.SerialSnapshotToJSONTest 抛出异常:System.ArgumentException:对象序列化为字符串。预期的 JObject 实例。”:root.Add("time", JObject.FromObject(time, serializer));
    • 使用JToken.FromObject(time, serializer),而不是JObject.FromObject(time, serializer)。前者将转换为任何类型的 JToken(在本例中为包含字符串的 JValue)。后者期望转换成JObject,因为转换器输出的是字符串,所以这不起作用。
    • 有用的答案。是否有可能以纯 DateTimeOffset 形式(2017-05-08T07:09:00+01:00)获得序列化?使用var settings = new JsonSerializerSettings().ConfigureForNodaTime(DateTimeZoneProviders.Serialization);,我得到序列化值2017-05-08T07:08:00Z,实际上是相同的,但为了与旧项目兼容,我需要得到DateTimeOffset序列化格式
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    • 2021-01-19
    • 1970-01-01
    • 1970-01-01
    • 2017-02-27
    相关资源
    最近更新 更多