C# 在使用JsonReader时,有没有办法倒带或后退?

C# 在使用JsonReader时,有没有办法倒带或后退?,c#,json.net,C#,Json.net,我试图从JSON对象输入流中读取第一个属性名,然后根据它的值,可能“倒带”并读取整个对象 我可以很容易地读懂第一个属性名,就像 JsonReader reader = ...; while (reader.Read()) { if (reader.TokenType == JsonToken.PropertyName) { // this is the first property break; } } 但我看不到任何方法来后退或倒带读者 虽然我知道底层流可能不支持较低

我试图从JSON对象输入流中读取第一个属性名,然后根据它的值,可能“倒带”并读取整个对象

我可以很容易地读懂第一个属性名,就像

JsonReader reader = ...;
while (reader.Read()) {
  if (reader.TokenType == JsonToken.PropertyName) {
    // this is the first property
    break;
  }
}
但我看不到任何方法来后退或倒带读者

虽然我知道底层流可能不支持较低级别的查找,但我希望我们已经读过的JSON标记可以以某种方式倒带和重新解析

如果这是不可能的,那么有没有办法只读取对象的属性名而不解析每个属性的内容?我希望避免只为了检查一个属性而阅读整篇文章两次。

否。是一个只向前阅读的阅读器。如果不从一开始就进行彻底的重做,就无法“倒带”或回到早期阶段。如果希望能够看到早期的信息,则需要在读取时将其存储到变量中

JsonReader
确实提供了一种方法,可用于跳过特定令牌的子项。因此,如果您读取了您不感兴趣的属性的名称,并且下一个标记是对象或数组的开始,那么您可以使用
Skip
直接移动到该对象或数组的结束标记

下面是一个简单的示例,它使用此技术仅读取JSON对象的根属性名称,但跳过所有值

string json = @"
{
  ""resultCode"": 200,
  ""message"": ""OK"",
  ""searchTerms"": [
    {
      ""attribute"": ""keywords"",
      ""operator"": ""contains"",
      ""values"": [ ""ipsum"" ]
    }
  ],
  ""count"": 2,
  ""items"": [
    {
      ""id"": 1,
      ""name"": ""foo"",
      ""sizes"": [ ""small"", ""meduim"", ""large"" ],
      ""description"": ""Lorem ipsum dolor sit amet""
    },
    {
      ""id"": 2,
      ""name"": ""bar"",
      ""sizes"": [ ""tiny"", ""huge"" ],
      ""description"": ""Neque porro quisquam est qui dolorem ipsum""
    }
  ]
}";

using (StringReader sr = new StringReader(json))
using (JsonTextReader reader = new JsonTextReader(sr))
{
    while (reader.Read())
    {
        if (reader.TokenType == JsonToken.PropertyName)
        {
            string propName = (string)reader.Value;
            Console.WriteLine(propName);

            // advance to property value
            reader.Read();

            // if the value is an object or array, skip over its children
            if (reader.TokenType == JsonToken.StartObject ||
                reader.TokenType == JsonToken.StartArray)
                reader.Skip();
        }
    }
}
输出:

resultCode
message
searchTerms
count
items

Fiddle:

我对System.Text.Json提出了同样的问题,我找到了一个解决方案,我想我应该在这里分享答案

正如Levi Broderick所建议的,新的
Utf8JsonReader
是一个结构,这意味着它可以随意复制

Utf8JsonReader-reader2=读取器;
reader2.Read();/。。。用读者的副本做一些事情
//在这里,最初的读者没有改变,仍然是你留下它的地方。
这样,您就可以像我一样两次解析数据,或者

对于Newtonsoft.Json,我最终使用了
JToken.ReadFrom(reader)
,然后在那里完成了我的工作。看

JToken令牌=JToken.ReadFrom(读卡器);
var left=token.ToObject(序列化程序);
var right=token.ToObject(序列化程序);

感谢您发布您的解决方案,它提供了非常有用的信息。