Flamy
Flamy

Reputation: 313

How to serialize and deserialize a class with byte array as a member in c#

I am trying to send data between 2 process in the form of byte streams, which is working fine for almost all the classes but one problem i am having is that the deserilization fails if the class of the object has a byte array inside it and gives me an error stating the assembly where the serilization took place cannot be loaded. I cannot include the assembly in here because both sender and receiver are different applications.

Is there a way to fix this?

Edit: Sorry it turns out that even normal classes cannot be deserialized in the other end

Edit: And one of the applications out of the 2 uses .Net 2.0

public static byte[] SerializeToByteArray(this object obj)
{
    if (obj == null)
    {
        return null;
    }
    var bf = new BinaryFormatter();
    using (var ms = new MemoryStream())
    {
        bf.Serialize(ms, obj);
        return ms.ToArray();
    }
}

public static T Deserialize<T>(this byte[] byteArray) where T : class
{
    if (byteArray == null)
    {
        return null;
    }
    using (var memStream = new MemoryStream())
    {
        var binForm = new BinaryFormatter();
        memStream.Write(byteArray, 0, byteArray.Length);
        memStream.Seek(0, SeekOrigin.Begin);s
        var obj = (T)binForm.Deserialize(memStream);
        return obj;
    }
}

Upvotes: 2

Views: 10935

Answers (1)

Woodman
Woodman

Reputation: 1137

I'd propose you to use DataContractSerializer (this MSDN link also have example of how class should be decorated with attributes).

Then you can (de)serialize such class to/from binary form easily:

public static byte[] SerializeToByteArray<T>(this T obj) where T : class
{
    if (obj == null)
    {
        return null;
    }
    using (var ms = new MemoryStream())
    {
        var serializer = new DataContractSerializer(typeof(T));
        serializer.WriteObject(ms, obj);
        return ms.ToArray();
    }
}

public static T Deserialize<T>(this byte[] byteArray) where T : class
{
    if (byteArray == null)
    {
        return default(T);
    }
    using (var memStream = new MemoryStream(byteArray))
    {
        var serializer = new DataContractSerializer(typeof (T));
        var obj = (T) serializer.ReadObject(memStream);
        return obj;
    }
}

use return default(T); instead of return null; , because T might be non-nullable
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/default

[Update] Warning! this is still not the best solution, as you'll have to define totally equal classes in both applications and pass them as generic parameter to these functions

[EDIT] Since you have to use .net 2.0 then you need to fall back to XMLSerialization. It's not as convenient as DataContract serialization, but it should work. Here is starting page for this topic on MSDN Below is code for serialization/deserialization

public static byte[] SerializeToByteArray<T>(this T obj) where T : class
{
    if (obj == null)
    {
        return null;
    }
    using (var ms = new MemoryStream())
    {
        var serializer = new XmlSerializer(typeof(T));
        serializer.Serialize(ms, obj);
        return ms.ToArray();
    }
}

public static T Deserialize<T>(this byte[] byteArray) where T : class
{
    if (byteArray == null)
    {
        return null;
    }
    using (var memStream = new MemoryStream(byteArray))
    {
        var serializer = new XmlSerializer(typeof(T));
        var obj = (T)serializer.Deserialize(memStream);
        return obj;
    }
}

Upvotes: 3

Related Questions