1

I have a working XML Serializer which serializes a C# object to an entity in AutoCAD. I'd like to be able to do the same thing but with Binary Serialization for the cases in which XML does not work. So far my serialization method looks like this:

public static void BinarySave(Entity entityToWriteTo, Object objToSerialize, string key = "default")
{
    using (MemoryStream stream = new MemoryStream())
    {
        BinaryFormatter serializer = new BinaryFormatter();
        serializer.Serialize(stream, objToSerialize);
        stream.Position = 0;

        ResultBuffer data = new ResultBuffer();

        /*Code to get binary serialization into result buffer*/

        using (Transaction tr = db.TransactionManager.StartTransaction())
        {
            using (DocumentLock docLock = doc.LockDocument())
            {
                if (!entityToWriteTo.IsWriteEnabled)
                {
                    entityToWriteTo = tr.GetObject(entityToWriteTo.Id, OpenMode.ForWrite) as Entity;
                }

                if (entityToWriteTo.ExtensionDictionary == ObjectId.Null)
                {
                    entityToWriteTo.CreateExtensionDictionary();
                }

                using (DBDictionary dict = tr.GetObject(entityToWriteTo.ExtensionDictionary, OpenMode.ForWrite, false) as DBDictionary)
                {
                    Xrecord xrec;

                    if (dict.Contains(key))
                    {
                        xrec = tr.GetObject(dict.GetAt(key), OpenMode.ForWrite) as Xrecord;
                        xrec.Data = data;
                    }

                    else
                    {
                        xrec = new Xrecord();
                        xrec.Data = data;
                        dict.SetAt(key, xrec);
                        tr.AddNewlyCreatedDBObject(xrec, true);
                    }

                    xrec.Dispose();
                }

                tr.Commit();
            }

           data.Dispose();
        }
    }
}

It's heavily based on my XML Serializer except I have no idea how to get the serialized object into a resultbuffer to be added to the Xrecord of entityToWriteTo.

dbc
  • 104,963
  • 20
  • 228
  • 340
Nick Gilbert
  • 4,159
  • 8
  • 43
  • 90
  • 2
    I'm just going to advise: I *regularly* see victims of `BinaryFormatter` - who due to some small refactor or revision cannot deserialize their data; I can't think of very many scenarios when I would actually advise people to use `BinaryFormatter`. Binary serialization *itself* is fine - there are a number of perfectly good binary serialization formats; I'm talking *only* about `BinaryFormatter` itself – Marc Gravell Apr 21 '15 at 21:25
  • I'm not sure if it would it would work, and maybe @Marc Gravel could ring in on this. But i believe protobuf could handle this task. I believe it has the functionality to serialize external objects. – Trae Moore Apr 25 '15 at 14:55
  • @Trae yep, protobuf-net will work for a lot of models - not all. I'd have to see specifics to comment in more detail – Marc Gravell Apr 25 '15 at 17:06

1 Answers1

1

If XML isn't working for you for some reason, I'd suggest trying a different textual data format such as JSON. The free and open-source JSON formatter Json.NET has some support for situations that can trip up XmlSerializer, including

Plus, JSON is quite readable so you may be able to diagnose problems in your data by visual examination.

That being said, you can convert the output stream from BinaryFormatter to a base64 string using the following helper methods:

public static class BinaryFormatterHelper
{
    public static string ToBase64String<T>(T obj)
    {
        using (var stream = new MemoryStream())
        {
            new BinaryFormatter().Serialize(stream, obj);
            return Convert.ToBase64String(stream.GetBuffer(), 0, checked((int)stream.Length)); // Throw an exception on overflow.
        }
    }

    public static T FromBase64String<T>(string data)
    {
        using (var stream = new MemoryStream(Convert.FromBase64String(data)))
        {
            var formatter = new BinaryFormatter();
            var obj = formatter.Deserialize(stream);
            if (obj is T)
                return (T)obj;
            return default(T);
        }
    }
}

The resulting string can then be stored in a ResultBuffer as you would store an XML string.

dbc
  • 104,963
  • 20
  • 228
  • 340