9

I want to serailize my object and used BinaryFormatter class.

public static byte[] BinarySerialize(IMessage message)
{
    using (var stream = new MemoryStream())
    {
        var formatter = new BinaryFormatter();

        formatter.Serialize(stream, message);

        return stream.ToArray();
    }
}

But when I run the code, throws an exception.

SerializationException: Object is not marked as serializable.

I think this exception thrown by BinaryFormatter.

I do not want to mark as [Serializable] my objects. Or my library users may forget mark as [Serializable] their own Messages.

Is there any other way to binary serialize my objects without using [Serializable] attribute?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
barteloma
  • 6,403
  • 14
  • 79
  • 173
  • Check Protobuf, that shall not need Serializable attribute – Mrinal Kamboj Sep 01 '16 at 06:43
  • var result = BinarySerialize(JsonConvert.SerializeObject(message)); – CRice Sep 01 '16 at 06:51
  • 1
    var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message)); – CRice Sep 01 '16 at 06:51
  • go through two stages of serialization? – CRice Sep 01 '16 at 06:51
  • How to deserialize? Binary deserialization returns original object that namespace and class info. But Json deserialization returns only object like this {"id": "000"} – barteloma Sep 01 '16 at 11:18
  • You then need to Json deserialize back to the message. You will need to know the target type at that point which might be a problem since you start from an Interface. Can the caller provide this... and your signature could be Deserialize(byte[] bytes) where T: IMessage – CRice Sep 02 '16 at 03:30
  • You need to also consider what the various serializers serialize, e.g. Json and Xml serializers serialize properties while the BinaryFormatter serializes the fields. This can be important e.g. if you [JsonIgnore] internal data for the UI, but still need to serialize them internally e.g. for a distributed cache. – Etherman Nov 04 '20 at 14:00

3 Answers3

5

Since [Serializable] attribute cannot be added runtime, there are nooptions if you want to stick to the .Net built in Serialization.

You can

  1. Use ISerializable interface in IMessage so that users has to implement Serialization in their implementations
  2. Use an external library such as: http://sharpserializer.codeplex.com/ And by the way, they have moved to GitHub. See: https://github.com/polenter/SharpSerializer

    public static byte[] BinarySerialize(IMessage message)
    {
        using (var stream = new MemoryStream())
        {
            var serializer = new SharpSerializer(true);
    
            serializer.Serialize(message, stream );
    
            return stream.ToArray();
        }
    }   
    
  3. Use JSON serialization

Roberto B
  • 542
  • 5
  • 13
Low Flying Pelican
  • 5,974
  • 1
  • 32
  • 43
2

In addition to the other answers regarding 3rd party libs, depending on your needs you may choose to use XmlSerializer. (Better yet use a JSON serializer that doesn't require the SerializeableAttribute.)

These serializers do not require [Serializeable]. However, the XmlSerializer doesn't allow serialization of interfaces either. If you are good with concrete types it works. Compare serialization options.

E.G.

void Main()
{
    var serialized = Test.BinarySerialize(new SomeImpl(11,"Hello Wurld"));
}

public class Test
{
    public static string BinarySerialize(SomeImpl message)
    {
        using (var stream = new StringWriter())
        {
            var formatter = new XmlSerializer(typeof(SomeImpl));

            formatter.Serialize(stream, message);

            return stream.ToString().Dump();
        }
    }

}

public class SomeImpl
{
    public int MyProperty { get;set;}
    public string MyString { get;set; }

    public SomeImpl() {}

    public SomeImpl(int myProperty, String myString)
    {
        MyProperty = myProperty;
        MyString = myString;
    }
}
P.Brian.Mackey
  • 43,228
  • 68
  • 238
  • 348
1

To avoid Net4x built in Serialization that require the [Serializable] attribute, use Newtonsoft.Json or System.Text.Json in netcore 3.1+ or Net5

 
string json= JsonConvert.SerializeObject(message); 

//or System.Text.Json in netcore 3.1+
string json=  System.Text.Json. JsonSerializer.Serialize(message);
M.Hassan
  • 10,282
  • 5
  • 65
  • 84