10

我正在尝试使用 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<string>() 只是调用Json.NET 已经解析ToString的一些内部对象。DateTime我可以做类似的事情

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

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

有什么方法可以获取 JSON 值的原始字符串值?

4

1 回答 1

19

There is a NodaTime.Serialization.JsonNet package available on NuGet that seems to be aimed exactly at this situation. Here is how to set it up:

After downloading and installing the package in your solution, add the following using statement to your code:

using NodaTime.Serialization.JsonNet;

Set up your serializer like this:

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

Then, when you deserialize, you can get a LocalDateTime from the JObject using ToObject<LocalDateTime>(serializer) like this:

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);
    }
}
于 2014-01-10T17:19:06.313 回答