s d*_*s d 4 .net c# json timespan json.net
我想解析 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
Run Code Online (Sandbox Code Playgroud)
我什至试过:
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
Run Code Online (Sandbox Code Playgroud)
这至少会产生一个令牌类型 JTokenType.TimeSpan的JValue对象,但在我解析它时仍然显示为 JTokenType.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 中的可扩展性非常好。