Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Newtonsoft Json.net - how to serialize content of a stream?

Tags:

c#

json.net

I need to convert to JSON arbitrary content of a memory stream. Here is a quick example of what I am trying to do:

class Program
{
    class TestClass { public int Test1;}
    static void Main(string[] args)
    {
        var ms = new MemoryStream();
        var writer = new StreamWriter(ms);
        writer.Write(new TestClass());
        writer.Flush();
        ms.Position = 0;

        var json = JsonConvert.SerializeObject(/*???*/, Formatting.Indented);
        Console.Write(json);
        Console.Read();
    }
}

Not sure what to pass to the SerializeObject method. If I pass the MemoryStream (variable ms) I get an error:

An unhandled exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll

Additional information: Error getting value from 'ReadTimeout' on 'System.IO.MemoryStream'.

Is that possible to serialize arbitrary content of a stream ?

Thank you

like image 250
user1044169 Avatar asked May 19 '15 16:05

user1044169


People also ask

How do you serialize JSON?

NET objects as JSON (serialize) To write JSON to a string or to a file, call the JsonSerializer. Serialize method. The JSON output is minified (whitespace, indentation, and new-line characters are removed) by default.

Does JSON serialize data?

Json namespace provides functionality for serializing to and deserializing from JavaScript Object Notation (JSON). Serialization is the process of converting the state of an object, that is, the values of its properties, into a form that can be stored or transmitted.

What is the difference between JSON and serialization?

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). If you serialize this result it will generate a text with the structure and the record returned.

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

To serialize a . Net object to JSON string use the Serialize method. It's possible to deserialize JSON string to . Net object using Deserialize<T> or DeserializeObject methods.


1 Answers

Serializing and deserializing content of a MemoryStream can be achieved using a converter:

public class MemoryStreamJsonConverter : JsonConverter
{
  public override bool CanConvert(Type objectType)
  {
     return typeof(MemoryStream).IsAssignableFrom(objectType);
  }

  public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  {
     var bytes = serializer.Deserialize<byte[]>(reader);
     return bytes != null ? new MemoryStream(bytes) : new MemoryStream();
  }

  public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  {
     var bytes = ((MemoryStream)value).ToArray();
     serializer.Serialize(writer, bytes);
  }
}

Then your code could look like that (I changed "new TestClass()" to "Test string" for easier comparison of json serialization and deserialization):

private void CheckJsonSerialization()
{
   var ms = new MemoryStream();
   var writer = new StreamWriter(ms);
   writer.WriteLine("Test string");
   writer.Flush();
   ms.Position = 0;

   var json = JsonConvert.SerializeObject(ms, Formatting.Indented, new MemoryStreamJsonConverter());
   var ms2 = JsonConvert.DeserializeObject<MemoryStream>(json, new MemoryStreamJsonConverter());
   var reader = new StreamReader(ms2);
   var deserializedString = reader.ReadLine();

   Console.Write(json);
   Console.Write(deserializedString);
   Console.Read();
}

Such converter can be also used when Stream is a property of a serialized object:

  public class ClassToCheckSerialization
  {
     public string StringProperty { get; set; }

     [JsonConverter(typeof(MemoryStreamJsonConverter))]
     public Stream StreamProperty { get; set; }
  }

  private void CheckJsonSerializationOfClass()
  {
     var data = new ClassToCheckSerialization();
     var ms = new MemoryStream();
     const string entryString = "Test string inside stream";
     var sw = new StreamWriter(ms);
     sw.WriteLine(entryString);
     sw.Flush();
     ms.Position = 0;
     data.StreamProperty = ms;
     var json = JsonConvert.SerializeObject(data);

     var result = JsonConvert.DeserializeObject<ClassToCheckSerialization>(json);
     var sr = new StreamReader(result.StreamProperty);
     var stringRead = sr.ReadLine();
     //Assert.AreEqual(entryString, stringRead);
  }
like image 79
Dariusz Wasacz Avatar answered Oct 11 '22 17:10

Dariusz Wasacz