Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct way to use JSON.NET to parse stream of JSON objects?

Tags:

c#

json.net

I have a stream of JSON objects that looks somewhat like this:

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

So basically a concatenated list of JSON objects without any separator. What's the proper way to deserialize those into an IEnumerable<T> using JSON.NET? At the moment I tried something like

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

But this fails with

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)

Obviously I need to move the reader after the Deserialize call, but how do I do this?

like image 493
Andrey Shchekin Avatar asked Oct 28 '14 05:10

Andrey Shchekin


People also ask

How do you serialize and deserialize an object in C# using JSON?

In Deserialization, it does the opposite of Serialization which means it converts JSON string to custom . Net object. In the following code, it calls the static method DeserializeObject() of the JsonConvert class by passing JSON data. It returns a custom object (BlogSites) from JSON data.

What is Newtonsoft JSON used for?

The Newtonsoft. Json namespace provides classes that are used to implement the core services of the framework. The default JSON name table implementation. Instructs the JsonSerializer how to serialize the collection.

What is JSON serialize and deserialize?

JSON is a format that encodes objects in a string. Serialization means to convert an object into that string, and deserialization is its inverse operation (convert string -> object).


1 Answers

I think if you change your loop around slightly everything should work:

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

Note that you must iterate over the IEnumerable<TResult> while the Stream passed to this method is open:

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

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

Example: https://dotnetfiddle.net/Y2FLuK

Sample on JsonNet site: Read Multiple Fragments With JsonReader

like image 111
Andrew Whitaker Avatar answered Oct 22 '22 06:10

Andrew Whitaker