如何解析Newtonsoft JSON中的TimeSpan值

我想解析JSON字符串并使用token.Type属性来检测JTokenType.TimeSpan类型的JTokenType.TimeSpan

我无法弄清楚如何在输入字符串中表达TimeSpan,一切似乎都被解释为JTokenType.String。

 var timeSpanString = TimeSpan.FromHours(1).ToString(); testString = string.Format(@"{{""Value"": ""{0}"" }}", timeSpanString); var statObject = JObject.Parse(testString); JToken token = statObject["Value"]; var tokenValue = token.ToString(); var tokenType = token.Type; // JTokenType.String 

我甚至尝试过:

 JValue jValue = new JValue("test"); jValue.Value = TimeSpan.FromHours(1); bool isTimeSpan = jValue.Type == JTokenType.TimeSpan; // true! testString = string.Format(@"{{""Value"": ""{0}"" }}", jValue.Value); var statObject = JObject.Parse(testString); JToken token = statObject["Value"]; var tokenValue = token.ToString(); var tokenType = token.Type; // JTokenType.String 

至少生成一个tokenType JTokenType.TimeSpan的JValue对象,但在解析它时仍然显示为JTokenType.String。

这适用于DateTime对象。 如何表达输入字符串,使得解析的值类型为JTokenType.TimeSpan

基于我在使用JSON.NET一段时间后所看到的情况,您将永远不会使用默认设置解析字符串并检索类型为JTokenType.TimeSpan的令牌(对于其他一些类型也是如此,例如Guid或者Uri)。 我很好地猜测了为什么会这样(根据我几年前使用DataContractJsonSerializer工作的经验)。

基本上,这是解析器可以从输入中检索多少信息的问题。 JSON是一个非常简单的语法,只知道数字布尔字符串 (除了数组和对象)。 许多CLR类型没有本机JSON类型(Uri,DateTime,DateTimeOffset,TimeSpan等),因此当任何JSON解析器读取数据时,它将尝试使用最佳匹配。

如果要将JSON字符串反序列化为CLR数据类型,则序列化程序可以使用一些其他信息来消除JSON字符串映射到的内容 – 该值被反序列化的字段/属性的类型。 但是,当您将JSON数据反序列化为JToken对象图时,没有其他信息,JSON.NET必须选择一种类型。 反序列化JSON字符串的最自然类型是CLR字符串。

但为什么日期被正确反序列化为JTokenType.Date ? IIRC,JSON.NET阅读器有一个特殊的日期代码(由DateParseHandling枚举控制),它试图将解析后的字符串与某些预定义格式(ISO 8601或旧的Microsoft ASP.NET AJAX格式)相匹配,如果是找到一个匹配它的字符串,它将把它读作DateTime (或DateTimeOffset )而不是字符串。 我不知道是否可以扩展该行为以支持TimeSpan或其他类型,但我不会感到惊讶,因为JSON.NET中的可扩展性非常好。

如果您正在尝试解析TimeSpan,则需要将其包围在引号中:’“12:00:00”’

如果您序列化TimeSpan并查看字符串结果,它看起来像:“\”12:00:00 \“”

至少这对我使用NewtonSoft.JsonConvert。 我的数据库中的字符串“12:00:00”(包括引号)。

并使用JsonConvert.DeserializeObject(dbString)返回正常。

刚遇到同样的问题,并且能够这样做:

 string json = "{ \"span\": \"00:00:15\"}"; JToken token = JToken.Parse(json); TimeSpan span = token["span"].ToObject();