Yoav Haik
Yoav Haik

Reputation: 96

C# proper way to construct ISerializable interface?

I recently made my own custom formatter, it takes a runtime object and writes down an object graph of it in a string format then takes that string and converts it back to a runtime object. Example: [CustomFormatter.Btype, CustomFormatter, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null==[a==5][b==0]]

after messing around with primitive objects (int, bool, float...) I tried to serialize a Bitmap object into string using the ISerializable interface and it worked well but when I try to reconstruct the object back I'm getting an error System.MissingMethodException: Constructor on type 'System.Drawing.Bitmap' not found.

If bitmap doesn't have a constructor which takes SerializationInfo and StreamingContext as parameters how else can an object which inherits the ISerializable interface be constructed?

This part is is the main issue but I can include the whole code:

        private static object SeriObjConstructor(Type objType, ref string dataInfo, ref int location)
        {
            SerializationInfo info = new SerializationInfo(objType, new FormatterConverter());
            StreamingContext context = new StreamingContext(StreamingContextStates.All);
            location += serializerEntry.Length;
            while (!CheckHitOperator(dataInfo, serializerExit, ref location))
            {
                KeyValuePair<string, Type> serializedObj = GetSerialiedName(ref dataInfo, ref location); //<name, type>
                info.AddValue(serializedObj.Key, Construction(serializedObj.Value, ref dataInfo, ref location));
            }
            location += serializerExit.Length;
            location += endClass.Length;

            var instance = Activator.CreateInstance(objType, info, context); //THROWS AN ERROR
            return instance;
        }

Upvotes: 1

Views: 400

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1062895

If you are forced to for legacy .NET Framework reasons, and you are taking over the role of the serializer engine: you can construct raw objects using FormatterServices.GetUninitializedObject. This API is explicitly intended for use with things like serialization, but should be treated as an advanced/exotic feature, and needs great care. Bad things can happen in some cases (fields not initialized, etc).

Quite honestly there is no correct way of working with the ISerializable interface in 2020 - that entire API is deprecated and obsolete, and isn't widely supported in .NET Core / .NET 5, and I would not recommend starting new work with it. More details about the problems/reasons are here: https://blog.marcgravell.com/2020/03/why-do-i-rag-on-binaryformatter.html, and many other, non-deprecated, serialization frameworks exist.

Upvotes: 1

Related Questions