Essentials Of Serialization - Binary Serialization

The serialization and deserialization process is one of the techniques we use most often when working with data in XML, JSON, etc., formats, which are external technologies on the .NET platform. In this article, we will talk about the essentials of serialization and binary serialization. We will have a separate article for each type of serialization.

PS: You can download the codes from here.

What is the process of Serialization and Deserialization?

The serialization process is the process of converting the MOVCUD object into another technological unit (XML, JSON, binary, etc.).

Deserialization is the process of converting information stored in that technological unit back into a .NET object.

When is serialization used?

The serialization process is most often used to transfer or store data contained in objects on the .NET platform, transforming them into another technological unit. Example: If we have any object and we need to save the data in this object in XML format or convert it to XML or JSON and send it through the service, then we serialize that object.

Serialization is not conversion!

The serialization process is usually similar to the conversion process. Suppose the conversion is simply the name used to convert from one type to another within the .NET ecosystem. In that case, serialization goes further and is the process of converting to a technological entity that exists independently outside the .NET platform.

For the object to be serializable, it is necessary to specify the class with the Serializable attribute. If we do not specify this attribute during serialization, we encounter the following problem.

Essentials of Serialization

If we do not want any member of the class to be serialized, then we mark that member with the NonSerializable attribute. This attribute is not valid for properties! That member must be a field at serialization time.

Essentials of Serialization

Since the attribute cannot be passed to the child class at the derivation time, the deriving class must also be marked with the Serializable attribute.

There are 4 basic forms of serialization in the .NET platform:

  1. Binary serialization
  2. XML serialization
  3. JSON serialization
  4. SOAP serialization

Binary serialization

If you need to serialize and store any object in binary format or send it from one computer to another with RPC, then you need to serialize that object.

It is possible to serialize the given information in binary format through the BinaryFormatter class located inside the Mscorlib assembly. For this, you need to add the System.Runtime.Serialization.Formatters.Binary namespace.

Note that the IFormatter interface designed for Binary and SOAP serialization has the following functionality.

public interface IFormatter {
    SerializationBinder Binder {
        get;
        set;
    }
    StreamingContext Context {
        get;
        set;
    }
    ISurrogateSelector SurrogateSelector {
        get;
        set;
    }
    object Deserialize(Stream serializationStream);
    void Serialize(Stream serializationStream, object graph);
}

We will use the FileStream class in the System.IO namespace to serialize the given object because the serializable object is written to the file system. If you don't want to write the Object to the hard disk, but to store it in the RAM or transfer it over the network, then you can use other Stream options.

To serialize the object, we use the Serialize() method of the BinaryFormatter class. This method basically takes 2 arguments. In one of the arguments, we indicate the Stream object, exactly where we want to write the object. In the second argument, we indicate which object to serialize.

We have created 2 projects in our solution for serialization. First, the SerializableObjects project contains our serializable classes:

[Serializable]
public class Card {
    public int Id {
        get;
        set;
    }
    public string Number {
        get;
        set;
    }
    public ushort CVC {
        get;
        set;
    }
    public DateTime ExpireDate {
        get;
        set;
    }
    public string CardHolder {
        get;
        set;
    }
}

The Person class is as follows:

[Serializable]
public class Person {
    public Person() {
        Cards = new List();
    }
    public int Id {
        get;
        set;
    }
    public string Name {
        get;
        set;
    }
    public string Surname {
        get;
        set;
    }
    public byte Age {
        get;
        set;
    }
    public string Email {
        get;
        set;
    }
    public List Cards {
        get;
        set;
    }
}

To keep the project as simple as possible, we store data with RAM modeling rather than directly with the database. For this, we have a class called InMemoryDb:

public class InMemoryDb {
    public List People {
        get;
        set;
    }
    public List Cards {
        get;
        set;
    }
    public InMemoryDb() {
        #region initialize datas
        Cards = new List {
            new Card {
                Id = 1,
                    CardHolder = "MR. IZUKU MIDORIYA",
                    CVC = 456,
                    ExpireDate = DateTime.Now.AddYears(2),
                    Number = "1234-1234-1234"
            },
            new Card {
                Id = 2,
                    CardHolder = "MR. IZUKU MIDORIYA",
                    CVC = 233,
                    ExpireDate = DateTime.Now.AddYears(2),
                    Number = "1234-1234-1234"
            },
            new Card {
                Id = 3,
                    CardHolder = "MR. SHOTO TODOROKI",
                    CVC = 788,
                    ExpireDate = DateTime.Now.AddYears(2),
                    Number = "1999-1999-1999-1993"
            }
        };
        People = new List {
            new Person {
                Id = 1,
                    Age = 34,
                    Email = "[email protected]",
                    Name = "Izuku",
                    Surname = "Midoriya",
                    Cards = new List {
                        Cards[0], Cards[1]
                    }
            },
            new Person {
                Id = 2,
                    Age = 24,
                    Email = "[email protected]",
                    Name = "Katsumi",
                    Surname = "Bakugo"
            },
            new Person {
                Id = 3,
                    Age = 34,
                    Email = "[email protected]",
                    Name = "Shoto",
                    Surname = "Todoroki",
                    Cards = new List {
                        Cards[2]
                    }
            }
        };
        #endregion
    }
}

To perform Binary Serialization, we call the Serialize() method of the BinaryFormatter class in the following form:

InMemoryDb db = new InMemoryDb();
List people = db.People;
BinaryFormatter serializeAsBinary = new BinaryFormatter();
using(FileStream fs = new FileStream("personInfo.dat", FileMode.OpenOrCreate)) {
    serializeAsBinary.Serialize(fs, people[0]);
}

At the time of serialization in binary format, other classes included in the class are automatically serialized together with all their data.

After the object is serialized, if we open the personInfo.dat file, we will see such information.

Essentials of Serialization

From here, it is clear that during serialization, the values in the properties of the object are stored in the file in the form of fields.

If we want to deserialize the given object, then it is enough to read that file through Stream and indicates to which object the information in it should be deserialized.

InMemoryDb db = new InMemoryDb();
List people = db.People;
BinaryFormatter serializeAsBinary = new BinaryFormatter();
using(FileStream fs = new FileStream("personInfo.dat", FileMode.OpenOrCreate)) {
    serializeAsBinary.Serialize(fs, people[0]);
}

Essentials of Serialization

The process of serialization and deserialization of the given object in the form of an array is performed in a similar way.

InMemoryDb db = new InMemoryDb();
List people = db.People;
BinaryFormatter serializeAsBinary = new BinaryFormatter();
using(FileStream fs = new FileStream("personInfo.dat", FileMode.OpenOrCreate)) {
    serializeAsBinary.Serialize(fs, people);
}
List peopleDeserialized = new List();
using(FileStream fs = new FileStream("personInfo.dat", FileMode.OpenOrCreate)) {
    peopleDeserialized = (List) serializeAsBinary.Deserialize(fs);
}
Console.WriteLine(peopleDeserialized[0].Name);

Essentials of Serialization


Similar Articles