且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在Newtonsoft JSON中解析TimeSpan值

更新时间:2023-01-17 22:51:22

基于一段时间以来我在使用JSON.NET时所看到的内容,使用默认设置,您将永远不会解析字符串并检索令牌.类型为JTokenType.TimeSpan(也与其他某些类型相同,例如Guid或Uri).我有一个很好的猜测,为什么会这样(根据我几年前在DataContractJsonSerializer工作的经验).

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). I have a pretty good guess of why this is the case (based on my experience working a few years ago with the DataContractJsonSerializer).

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

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). 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.

如果要将JSON字符串反序列化为CLR数据类型,则序列化器具有一些附加信息,可用于消除JSON字符串映射的歧义-值反序列化为的字段/属性的类型.但是,当您将JSON数据反序列化为JToken对象图时,没有其他信息,并且JSON.NET必须选择一种类型.反序列化JSON字符串最自然的类型是CLR字符串.

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. 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. The most natural type to deserialize a JSON string is, well, a CLR string.

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

But why do dates are deserialized correctly as 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. 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.