使用JSON.NET解析JSON对象流的正确方法是什么?

And*_*kin 13 c# json.net

我有一个JSON对象流,看起来有点像这样:

{...}{...}{...}{...}...
Run Code Online (Sandbox Code Playgroud)

所以基本上是没有任何分隔符的JSON对象的连接列表.将这些反序列化为IEnumerable<T>使用JSON.NET 的正确方法是什么?此刻我尝试了类似的东西

var serializer = new JsonSerializer();
serializer.CheckAdditionalContent = false;

using (var reader = new StreamReader(stream))
using (var jsonReader = new JsonTextReader(reader)) {
    reader.SupportMultipleContent = true;
    reader.Read();
    while (reader.TokenType != JsonToken.None) {
        yield return serializer.Deserialize<TResult>(reader);
    }
}
Run Code Online (Sandbox Code Playgroud)

但这失败了

Newtonsoft.Json.JsonSerializationException: Unexpected token while deserializing object: EndObject. Path '', line 1, position 55.
  at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
  at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
  at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
  at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)
Run Code Online (Sandbox Code Playgroud)

显然我需要在Deserialize通话结束后移动阅读器,但我该怎么办呢?

And*_*ker 16

我想如果你稍微改变你的循环一切应该工作:

public IEnumerable<TResult> ReadJson<TResult>(Stream stream)
{
    var serializer = new JsonSerializer();

    using (var reader = new StreamReader(stream))
    using (var jsonReader = new JsonTextReader(reader))
    {
        jsonReader.SupportMultipleContent = true;

        while (jsonReader.Read())
        {
            yield return serializer.Deserialize<TResult>(jsonReader);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,您必须遍历IEnumerable<TResult>,而Stream传递给此方法是开放的:

using (var stream = /* some stream */)
{
    IEnumerable<MyClass> result = ReadJson<MyClass>(stream);

    foreach (var item in result)
    {
        Console.WriteLine(item.MyProperty);
    }
}
Run Code Online (Sandbox Code Playgroud)

示例: https ://dotnetfiddle.net/Y2FLuK

  • @AmbroseLeung:我相信它告诉 `JsonTextReader` 文档中存在多个 JSON 片段。该问题提到了单个对象流(`{}{}{}`),这就是为什么该属性是必要的。 (2认同)