我想解析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
至少会生成tokenType JTokenType.TimeSpan的 JValue 对象,但在解析它时仍会显示为JTokenType.String。
这适用于DateTime对象。
如何表达输入字符串,使得解析的值类型为JTokenType.TimeSpan
?
答案 0 :(得分:4)
基于我在使用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中的可扩展性非常好。
答案 1 :(得分:1)
如果您尝试解析TimeSpan,则需要将其包围在引号中: ' “12:00:00”'
如果序列化TimeSpan并查看字符串结果,它看起来像: “\” 12:00:00 \ “”
至少这对我使用NewtonSoft.JsonConvert起作用了。我的数据库中的字符串“12:00:00”(包括引号)。
使用JsonConvert.DeserializeObject(dbString)返回正常。
答案 2 :(得分:0)
只是遇到了同样的问题,并且能够通过这种方式做到这一点:
string json = "{ \"span\": \"00:00:15\"}";
JToken token = JToken.Parse(json);
TimeSpan span = token["span"].ToObject<TimeSpan>();