【问题标题】:How to parse a TimeSpan value in Newtonsoft JSON如何在 Newtonsoft JSON 中解析 TimeSpan 值
【发布时间】:2012-11-21 00:30:53
【问题描述】:

我想解析 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

【问题讨论】:

  • 您是在寻找具有特定结构的处理输入,还是想要在 Json 块中查找时间跨度的任何实例?
  • 不确定您所说的“某种结构”是什么意思。输入将是一个 JSON 字符串,其中包含一个值,该值可以是多种类型之一:字符串、日期时间、时间跨度等。
  • var json = JsonConvert.SerializeObject(TimeSpan.FromHours(1)); var ts = JsonConvert.DeserializeObject<TimeSpan>(json);
  • @L.B - 这并没有真正的帮助。我需要知道如何格式化输入字符串,以便解析器将此字符串转换为 JObject,其中包含类型为 JTokenType.TimeSpan 的 JValue 令牌
  • @sd 序列化程序的存在是为了向您隐藏这些细节。请重新考虑一下。

标签: c# .net json json.net timespan


【解决方案1】:

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

基本上,这是解析器可以从输入中检索到多少信息的问题。 JSON 是一种非常简单的语法,它只知道 numbersbooleanstrings(除了数组和对象)。许多 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 中的可扩展性非常好。

【讨论】:

【解决方案2】:

如果您尝试解析 TimeSpan,则需要将其括在引号中: '"12:00:00"'

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

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

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

【讨论】:

    【解决方案3】:

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

    string json = "{ \"span\": \"00:00:15\"}";
    
    JToken token = JToken.Parse(json);
    
    TimeSpan span = token["span"].ToObject<TimeSpan>();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-16
      • 1970-01-01
      相关资源
      最近更新 更多