Подтвердить что ты не робот

Каков правильный способ использования JSON.NET для анализа потока объектов JSON?

У меня есть поток объектов JSON, который выглядит примерно так:

{...}{...}{...}{...}...

Таким образом, в основном объединенный список объектов 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);
    }
}

Но это не удается с помощью

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)

Очевидно, мне нужно переместить читателя после вызова Deserialize, но как это сделать?

4b9b3361

Ответ 1

Я думаю, что если вы немного измените свой цикл, все должно работать:

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);
        }
    }
}

Обратите внимание, что вы должны выполнять итерацию по IEnumerable<TResult>, пока Stream, переданный этому методу, открыт:

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

    foreach (var item in result)
    {
        Console.WriteLine(item.MyProperty);
    }
}

Пример: https://dotnetfiddle.net/Y2FLuK