如何在Newtonsoft JSON中解析TimeSpan值



我想解析JSON字符串,并使用token.Type属性来检测类型为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

它至少会生成一个JValue标记类型JTokenType.TimeSpan的对象,但在我解析它时仍然显示为JTokenTType.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有效。我的DB中的字符串"12:00:00"(包括引号)。

使用JsonConvert.DeserializeObject(dbString)返回fine。

刚刚遇到了同样的问题,可以这样做:

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

相关内容

  • 没有找到相关文章

最新更新