Is it possible to do .NET binary serialization of an object when you don't have the source code of the class?

c# binary serialization
types of serialization in c#

I am using BinaryFormatter to do binary serialization of some objects in C#. However, some of the objects contain classes that I access via a DLL and do not have the source code for, so I can't mark them with the Serializable attribute. Is there a straightforward way to serialize them anyway? I have a workaround which involves taking class NoSource and making a new class SerializableNoSource for which the constructor takes a NoSource object and extracts all the information I need from it, but it's hacky. Are there any better alternatives?

You could create a serialization surrogate.

Imagine that we have a class defined in a referenced assembly that we have no control over that looks like this:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public DriversLicense License;
}


// An instance of this type will be part of the object graph and will need to be 
// serialized also.
public class DriversLicense
{
    public string Number { get; set; }
}

In order to serialize this object you will need to define a serialization surrogate for each type in the object graph.

To create a serialization surrogate you simply need to create a type that implements the ISerializationSurrogate interface:

public class PersonSurrogate : ISerializationSurrogate
{
    /// <summary>
    /// Manually add objects to the <see cref="SerializationInfo"/> store.
    /// </summary>
    public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
    {
        Person person = (Person) obj;
        info.AddValue("Name", person.Name);
        info.AddValue("Age", person.Age);
        info.AddValue("License", person.License);
    }

    /// <summary>
    /// Retrieves objects from the <see cref="SerializationInfo"/> store.
    /// </summary>
    /// <returns></returns>
    public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
    {
        Person person = (Person)obj;
        person.Name = info.GetString("Name");
        person.Age = info.GetInt32("Age");
        person.License = (DriversLicense) info.GetValue("License", typeof(DriversLicense));
        return person;
    }
}

public class DriversLicenseSurrogate : ISerializationSurrogate
{
    /// <summary>
    /// Manually add objects to the <see cref="SerializationInfo"/> store.
    /// </summary>
    public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
    {
        DriversLicense license = (DriversLicense)obj;
        info.AddValue("Number", license.Number);
    }

    /// <summary>
    /// Retrieves objects from the <see cref="SerializationInfo"/> store.
    /// </summary>
    /// <returns></returns>
    public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
    {
        DriversLicense license = (DriversLicense)obj;
        license.Number = info.GetString("Number");
        return license;
    }
}

Then you need to let your IFormatter know about the surrogates by defining and initializing a SurrogateSelector and assigning it to your IFormatter.

private static void SerializePerson(Person person)
{
    if (person == null)
        throw new ArgumentNullException("person");

    using (var memoryStream = new MemoryStream())
    {
        //Configure our surrogate selectors.
        var surrogateSelector = new SurrogateSelector();
        surrogateSelector.AddSurrogate(typeof (Person), new StreamingContext(StreamingContextStates.All),
                                       new PersonSurrogate());
        surrogateSelector.AddSurrogate(typeof (DriversLicense), new StreamingContext(StreamingContextStates.All),
                                       new DriversLicenseSurrogate());

        //Serialize the object
        IFormatter formatter = new BinaryFormatter();
        formatter.SurrogateSelector = surrogateSelector;
        formatter.Serialize(memoryStream, person);

        //Return to the beginning of the stream
        memoryStream.Seek(0, SeekOrigin.Begin);

        //Deserialize the object
        Person deserializedPerson = (Person) formatter.Deserialize(memoryStream);
    }
}

Using a serialization surrogate is by no means straightforward, and can actually become quite verbose when the type you are trying to serialize has private & protected fields that need to be serialized.

But as you are already manually serializing the values you need, I don't think that is an issue. The use of a surrogate is a more unifom way of handling a scenario like this and should make you feel more comfortable.

Serialization (C#), NET .NET guide � Serialization in .NET If possible, make an object that could contain security-sensitive data nonserializable. If you don't exclude these fields from serialization, be aware that the data they store are exposed to any code that has For more information, see BinaryFormatter security guide. Using a serialization surrogate is by no means straightforward, and can actually become quite verbose when the type you are trying to serialize has private & protected fields that need to be serialized. But as you are already manually serializing the values you need, I don't think that is an issue.

You might be able to use Mono.Cecil to add the [SerializableAttribute] to the classes, but I wouldn't do it if there is another way of achieving the desired result.

Selective serialization, Okay, so you got something you need to binary serialize in . ability to not be able to override this and use the BinaryFormatter against an object not marked Serializable. You can programmatically tell it to ignore certain types (in case you don't patterns and practices to make developing reliable systems easie… 10 days� If possible, make an object that could contain security-sensitive data nonserializable. If the object must be serialized, apply the NonSerialized attribute to specific fields that store sensitive data. If you don't exclude these fields from serialization, be aware that the data they store are exposed to any code that has permission to serialize.

I agree with @Servy, if the author of the class did not anticipate that it would be serialized, you should not attempt to serialize it directly. So you're doing the right thing from an architectural standpoint. To make your current approach less, "hacky," consider implementing ISerializable for classes that contain references to non-serializable objects.

.NET Binary Object Serialization without Marking as Serializable , In our example, we are going to perform the below high-level steps in the code We will then use serialization to serialize the above object to a file If you don't mention this attribute, you will get an error when you try to serialize the class. Net"; IFormatter formatter = new BinaryFormatter(); Stream stream� .NET Assembly.Net Code Security.NET Access Modifiers.Net Architecture.NET Base Class Library.NET Common Language Runtime.NET Constants Enum Arrays collection.NET Data Types.NET Menu.NET Garbage Collection.Net Debug Trace.NET Properties.NET Form.NET Assemblies.NET Class Structures.NET Binding, viewing & filtering.NET Configuring Optimizing

Create a new class, inherit the existing class that is not marked with serialization attribute and implement ISerializable interface.

If the class is sealed then you can use Json.NET and then convert it to binary and vice versa (Sucks big time, use it if nothing else can help :)).

C# Serialization & Deserialization with Example, We've known for a long while that BinaryFormatter is a dangerous type and that it's If you do, then I don't see any reason to not agree with that, not be able to perform arbitrary object deserialization via BinaryFormatter . The methods do not access the serialization stream but instead allow you to alter the object before and after serialization, or before and after deserialization. The attributes can be applied at all levels of the type inheritance hierarchy, and each method is called in the hierarchy from the base to the most derived.

I know this is an old question but I recently found the need to serialize/deserialize DTOs that we have no control over its source code in binary format for performance reasons. Managed to find quite a few alternate binary serializers such as ZeroFormatter and Protobuf but all of them require decorating the DTOs with attributes or define a schema.

That led me down the path of creating my own binary serializer that is a quick replacement for JSON serializer in binary format which you may find useful: https://github.com/zachsaw/Binaron.Serializer

Remove BinaryFormatter from the shared framework in .NET 5 #29976, It doesn't matter to the serialization framework what you do with the serialized data. The latter two are serializable by default so you don't have to explicitly mark them as such. TypeAttributes for more detail and the other possible flags). SerializeObject creates a FileStream and a BinaryFormatter object and serializes� Using the XmlElementAttribute attribute to change the name of an XML element is not the only way to customize object serialization. You can also customize the XML stream by deriving from an existing class and instructing the XmlSerializer instance how to serialize the new class.

Binary Serialization with the Microsoft .NET framework and Delphi , NET. Binary serialization process which led to the discovery of some fundamental vulnerabilities more powerful than others, especially in what types of objects that they are able to manipulate. Don't serialize the event's delegate field trying to find classes which do something dangerous during deserialization: 1. To summarize and review, when serializing objects to a stream, you must use a .NET formatter class to control the serialization of the object to and from the stream. In addition to the serialized data, the serialization stream carries information about the object's type, including its assembly name, culture, and version.

[PDF] Are you my Type? Breaking .NET Through Serialization, I'll compare various frameworks and formats of serialization. to communicate between themselves so you'll have to serialize your objects for that. Normally you will use messaging frameworks that will do it for you but it's essential to understand what's JSON – http://james.newtonking.com/json, https:// servicestack.net/text C# tips and tricks 23 - How to serialize & deserialize object to JSON using newtonsoft.JSON library - Duration: 12:58. Ankpro Training 16,160 views

Serialization Performance comparison(XML,Binary,JSON,P), In computing, serialization (US spelling) or serialisation (UK spelling) is the process of Serialization of object-oriented objects does not include any of their associated it is possible for the common code to do both at the same time, and thus, weather, or ocean models, specific binary serialization standards have been�

Comments
  • For the record, encapsulating the object in another object that does know how to serialize itself as well as converting to/from the encapsulated object isn't hacky in my mind, it's entirely appropriate. Now, there could be something slicker or better out there, but I wouldn't consider your current approach fundamentally flawed.
  • This appears to be the textbook answer to truly serialize an unowned class that is not marked [Serializable]
  • If you want more information you can read chapter 23 of CLR via C# - Runtime Serialization.
  • Also found this relevant article on MSDN: msdn.microsoft.com/en-us/magazine/cc188950.aspx
  • "However, some of the objects contain classes that I access via a DLL and do not have the source code for"
  • You can I think create your own classe which could have the same properties as the object you don't have the source No ? Or extends it??
  • Extending won't work, copying the properties... that's the same as what he has now