57

I'm having an issue with serializing using memory stream. Here is my code:

/// <summary>
/// serializes the given object into memory stream
/// </summary>
/// <param name="objectType">the object to be serialized</param>
/// <returns>The serialized object as memory stream</returns>
public static MemoryStream SerializeToStream(object objectType)
{
    MemoryStream stream = new MemoryStream();
    IFormatter formatter = new BinaryFormatter();
    formatter.Serialize(stream, objectType);
    return stream;
}

/// <summary>
/// deserializes as an object
/// </summary>
/// <param name="stream">the stream to deserialize</param>
/// <returns>the deserialized object</returns>
public static object DeserializeFromStream(MemoryStream stream)
{
    IFormatter formatter = new BinaryFormatter();
    stream.Seek(0, SeekOrigin.Begin);
    object objectType = formatter.Deserialize(stream);
    return objectType;
} 

The error I'm getting is as follow: stream is not a valid binary format. The starting contents (in bytes) are: blah....

I'm not exactly sure what is causing the error. Any help would be greatly appreciated.

Example of the call:

Dog myDog = new Dog();
myDog.Name= "Foo";
myDog.Color = DogColor.Brown;

MemoryStream stream = SerializeToStream(myDog)

Dog newDog = (Dog)DeserializeFromStream(stream);
Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
gng
  • 715
  • 1
  • 5
  • 13

4 Answers4

66

This code works for me:

public void Run()
{
    Dog myDog = new Dog();
    myDog.Name= "Foo";
    myDog.Color = DogColor.Brown;

    System.Console.WriteLine("{0}", myDog.ToString());

    MemoryStream stream = SerializeToStream(myDog);

    Dog newDog = (Dog)DeserializeFromStream(stream);

    System.Console.WriteLine("{0}", newDog.ToString());
}

Where the types are like this:

[Serializable]
public enum DogColor
{
    Brown,
    Black,
    Mottled
}

[Serializable]
public class Dog
{
    public String Name
    {
        get; set;
    }

    public DogColor Color
    {
        get;set;
    }

    public override String ToString()
    {
        return String.Format("Dog: {0}/{1}", Name, Color);
    }
}

and the utility methods are:

public static MemoryStream SerializeToStream(object o)
{
    MemoryStream stream = new MemoryStream();
    IFormatter formatter = new BinaryFormatter();
    formatter.Serialize(stream, o);
    return stream;
}

public static object DeserializeFromStream(MemoryStream stream)
{
    IFormatter formatter = new BinaryFormatter();
    stream.Seek(0, SeekOrigin.Begin);
    object o = formatter.Deserialize(stream);
    return o;
}
Patrick
  • 674
  • 1
  • 8
  • 22
Cheeso
  • 189,189
  • 101
  • 473
  • 713
  • I implement the code that you suggested now and code throw this exception: Exception has been thrown by the target of an invocation. It occurs in the line object o = formatter.Deserialize(stream); What am I doing wrong? – meakgoz Mar 21 '14 at 12:39
  • okay I made a terrible mistake in the Deserialization constructor. One of my properties' info was wrong (i.e. ... = info.GetValue("HereWasWrong_ItWasNonExistingThing", typeof(int));) here it is a good link for this job, and someone may need it: http://www.codeproject.com/Articles/1789/Object-Serialization-using-C also thanks to Cheeso, the answer is good. – meakgoz Mar 21 '14 at 13:11
  • 2
    BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information. – Rodrigo Reis Dec 09 '21 at 23:47
7

Use Method to Serialize and Deserialize Collection object from memory. This works on Collection Data Types. This Method will Serialize collection of any type to a byte stream. Create a Seperate Class SerilizeDeserialize and add following two methods:

public class SerilizeDeserialize
{

    // Serialize collection of any type to a byte stream

    public static byte[] Serialize<T>(T obj)
    {
        using (MemoryStream memStream = new MemoryStream())
        {
            BinaryFormatter binSerializer = new BinaryFormatter();
            binSerializer.Serialize(memStream, obj);
            return memStream.ToArray();
        }
    }

    // DSerialize collection of any type to a byte stream

    public static T Deserialize<T>(byte[] serializedObj)
    {
        T obj = default(T);
        using (MemoryStream memStream = new MemoryStream(serializedObj))
        {
            BinaryFormatter binSerializer = new BinaryFormatter();
            obj = (T)binSerializer.Deserialize(memStream);
        }
        return obj;
    }

}

How To use these method in your Class:

ArrayList arrayListMem = new ArrayList() { "One", "Two", "Three", "Four", "Five", "Six", "Seven" };
Console.WriteLine("Serializing to Memory : arrayListMem");
byte[] stream = SerilizeDeserialize.Serialize(arrayListMem);

ArrayList arrayListMemDes = new ArrayList();

arrayListMemDes = SerilizeDeserialize.Deserialize<ArrayList>(stream);

Console.WriteLine("DSerializing From Memory : arrayListMemDes");
foreach (var item in arrayListMemDes)
{
    Console.WriteLine(item);
}
stop-cran
  • 4,229
  • 2
  • 30
  • 47
delta demon
  • 81
  • 1
  • 3
  • You can use this code to serialize the object(s) to and from a byte stream for storage in isolated storage or remote storage. With the help of this you can Persist a Collection Between Application Sessions. – delta demon Aug 30 '18 at 02:18
  • Thank you for this. Why everyone says that you cannot serialize an anonymous type though? – Matthew Sep 24 '20 at 09:04
4

It can be done easily by using System.Text.Json in .Net 6 using System.Text.Json;

Examlple ex = JsonSerializer.Deserialize<Example>(ms);
Console.WriteLine(ex.Value);

class Example
{
    string Value {get; set; }
}

Refer to this for serialization.

Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
3

BinaryFormatter may produce invalid output in some specific cases. For example it will omit unpaired surrogate characters. It may also have problems with values of interface types. Read this documentation page including community content.

If you find your error to be persistent you may want to consider using XML serializer like DataContractSerializer or XmlSerializer.

Maciej
  • 7,871
  • 1
  • 31
  • 36