【问题标题】:JToken does not deserialise like JsonConvert.DeserializeObjectJToken 不像 JsonConvert.DeserializeObject 那样反序列化
【发布时间】:2015-02-27 15:28:43
【问题描述】:

我在使用 JToken 反序列化 NodaTime.Instant 时遇到了麻烦。 使用 JsonConvert.DeserializeObject 时,问题不会出现。

以下示例代码失败并出现异常:

let jsonOptions =
  let n = new JsonSerializerSettings()
  n.ConfigureForNodaTime(NodaTime.DateTimeZoneProviders.Tzdb)

JToken.Parse("\"2010-02-12T23:22:00Z\"")
   .ToObject<Instant>(JsonSerializer.Create(jsonOptions));

异常的堆栈跟踪是:

deserialisation/deserialisation with JToken: Exception: NodaTime.Utility.InvalidNodaDataException: Unexpected token parsing Instant. Expected String, got Date.
at NodaTime.Serialization.JsonNet.NodaPatternConverter`1.ReadJsonImpl(JsonReader reader, JsonSerializer serializer)
at NodaTime.Serialization.JsonNet.NodaConverterBase`1.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.Linq.JToken.ToObject(Type objectType, JsonSerializer jsonSerializer)
at Newtonsoft.Json.Linq.JToken.ToObject[T](JsonSerializer jsonSerializer)

使用JsonConvert.DeserializeObject 反序列化相同的字符串是可行的。

JsonConvert.DeserializeObject<Instant>("\"2010-02-12T23:22:00Z\"", jsonOptions)

可在此处找到 2 个测试:

Tests.fsx

关于导致异常的原因有什么想法吗?

【问题讨论】:

  • 对于 StackOverflow,您需要复制代码的违规部分、预期输入和实际输出。这些应该是问题,作为一个最小可行的例子。要点链接可以保留,但应该是次要的。请编辑问题。谢谢。
  • 感谢@olav 的编辑!

标签: json f# json.net deserialization nodatime


【解决方案1】:

JToken.Parse 在内部使用 JSonTextReader 来解析字符串。 JSonTextReader 的默认行为是将示例中的时间日期字符串解析为DateTimeNodaPatternConverter 需要 string,而不是 DateTime。 您可以改用 JToken.Load 方法并传递一个将 DateParseHandling 设置为 DateParseHandling.NoneJSonTextReader

当您使用JsonConvert.DeserializeObject 时,它使用您在jsonOptions 中创建的JsonSerializerSettingsConfigureForNodaTime 方法将DateParseHandling 属性设置为DateParseHandling.None,这就是为什么JsonConvert.DeserializeObject 在您传递您所做的设置时起作用的原因。

【讨论】:

  • 据我所知,无法向JToken.Parse 提供设置似乎很奇怪...
  • 我猜这回答了我的问题。如果我需要添加比 NodaTime 更多的序列化选项会怎样?
猜你喜欢
  • 2020-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-08
  • 2015-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多