简体   繁体   English

如何解析Newtonsoft JSON中的TimeSpan值

[英]How to parse a TimeSpan value in Newtonsoft JSON

I'd like parse JSON string and use the token.Type property to detect values of type JTokenType.TimeSpan . 我想解析JSON字符串并使用token.Type属性来检测JTokenType.TimeSpan类型的JTokenType.TimeSpan

I can't work out how to express the TimeSpan in my input string, everything seems to be interpreted as JTokenType.String. 我无法弄清楚如何在我的输入字符串中表达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

I even tried: 我甚至尝试过:

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

Which at least produces a JValue object of tokenType JTokenType.TimeSpan, but still shows up as a JTokenType.String when I parse it. 至少生成一个tokenType JTokenType.TimeSpan的JValue对象,但在解析它时仍然显示为JTokenType.String。

This works perfectly for DateTime objects. 这适用于DateTime对象。 How can I express the input string such that the parsed value type is JTokenType.TimeSpan ? 如何表达输入字符串,使得解析的值类型为JTokenType.TimeSpan

Based on what I've seen while using JSON.NET for a while now, you will never, with the default settings, parse a string and retrieve a token with type JTokenType.TimeSpan (same for some other types as well, such as Guid or Uri). 根据我在使用JSON.NET一段时间后所看到的情况,您将永远不会使用默认设置解析字符串并检索类型为JTokenType.TimeSpan的令牌(对于其他一些类型也是如此,例如Guid或者Uri)。 I have a pretty good guess of why this is the case (based on my experience working a few years ago with the DataContractJsonSerializer ). 我很清楚为什么会出现这种情况(根据我几年前使用DataContractJsonSerializer工作的经验)。

Basically, it's a matter of how much information the parser can retrieve out of the input. 基本上,这是解析器可以从输入中检索多少信息的问题。 JSON is a very simple syntax which only knows about numbers , boolean and strings (in addition to arrays and objects). JSON是一个非常简单的语法,只知道数字布尔字符串 (除了数组和对象)。 Many CLR types don't have a native JSON type (Uri, DateTime, DateTimeOffset, TimeSpan, and so on), so when any JSON parser is reading the data, it will try to use the best match. 许多CLR类型没有本机JSON类型(Uri,DateTime,DateTimeOffset,TimeSpan等),因此当任何JSON解析器读取数据时,它将尝试使用最佳匹配。

If you're deserializing the JSON string into a CLR data type, then the serializer has some additional information that it can use to disambiguate what a JSON string maps to - the type of the field / property that value is being deserialized to. 如果要将JSON字符串反序列化为CLR数据类型,则序列化程序可以使用一些其他信息来消除JSON字符串映射到的内容 - 该值被反序列化的字段/属性的类型。 However, when you're deserializing a JSON data to a JToken object graph, there's no additional information, and JSON.NET has to choose one type. 但是,当您将JSON数据反序列化为JToken对象图时,没有其他信息,JSON.NET必须选择一种类型。 The most natural type to deserialize a JSON string is, well, a CLR string. 反序列化JSON字符串的最自然类型是CLR字符串。

But why do dates are deserialized correctly as JTokenType.Date ? 但为什么日期被正确反序列化为JTokenType.Date IIRC, the JSON.NET reader has a special code for dates (controlled by the DateParseHandling enumeration), which tries to match the parsed strings to some predefined formats (either ISO 8601 or the old Microsoft ASP.NET AJAX format), and if it finds a string which match it, it will read it as a DateTime (or DateTimeOffset ) instead of a string. IIRC,JSON.NET阅读器有一个特殊的日期代码(由DateParseHandling枚举控制),它试图将解析后的字符串与某些预定义格式(ISO 8601或旧的Microsoft ASP.NET AJAX格式)相匹配,如果是找到一个与之匹配的字符串,它将把它读作DateTime (或DateTimeOffset )而不是字符串。 I don't know whether it's possible to extend that behavior to also support TimeSpan or other types, but I wouldn't be surprised, since the extensibility in JSON.NET is quite good. 我不知道是否可以扩展该行为以支持TimeSpan或其他类型,但我不会感到惊讶,因为JSON.NET中的可扩展性非常好。

If you are trying to parse a TimeSpan it needs to be surrounded in quotations: '"12:00:00"' 如果您正在尝试解析TimeSpan,则需要将其包围在引号中:'“12:00:00”'

If you serialize a TimeSpan and look at the string result it looks like: "\\"12:00:00\\"" 如果您序列化TimeSpan并查看字符串结果,它看起来像:“\\”12:00:00 \\“”

At least this worked for me using NewtonSoft.JsonConvert. 至少这对我使用NewtonSoft.JsonConvert。 The string in my DB "12:00:00" (including the quotes). 我的数据库中的字符串“12:00:00”(包括引号)。

And using JsonConvert.DeserializeObject(dbString) returns fine. 并使用JsonConvert.DeserializeObject(dbString)返回正常。

Just ran into the same problem and was able to do it this way: 刚遇到同样的问题,并且能够这样做:

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

JToken token = JToken.Parse(json);

TimeSpan span = token["span"].ToObject<TimeSpan>();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM