4

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

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

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

4

3 回答 3

6

根据我在一段时间内使用 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 中的可扩展性非常好。

于 2012-11-22T04:29:59.487 回答
2

如果您尝试解析 TimeSpan 它需要用引号括起来:'"12:00:00"'

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

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

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

于 2016-05-20T21:59:56.200 回答
0

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

string json = "{ \"span\": \"00:00:15\"}";

JToken token = JToken.Parse(json);

TimeSpan span = token["span"].ToObject<TimeSpan>();
于 2018-07-03T08:20:23.310 回答