BinaryFormatter in C#: A Step‑by‑Step Serialization Guide

Serialization is a fundamental concept in .NET that allows objects to be converted into a format that can be easily stored or transmitted. BinaryFormatter, a built-in serialization mechanism in C#, enables the conversion of objects into a binary format for storage or transfer over a network.

While BinaryFormatter was commonly used in earlier versions of .NET, Microsoft has deprecated it in .NET 5 and later due to security concerns. However, understanding its functionality is still valuable, especially when working with legacy systems. This guide explores BinaryFormatter, how it works, and alternative serialization approaches for modern applications.


What Is BinaryFormatter?

BinaryFormatter is a class in the System.Runtime.Serialization.Formatters.Binary namespace that enables binary serialization and deserialization of objects. It is part of the .NET Framework and .NET Core (before .NET 5) and was widely used for object persistence and data transmission.

Key Features of BinaryFormatter:

  • Converts objects into a compact binary format

  • Supports complex object graphs, including circular references

  • Preserves type information during serialization

  • Works with custom and built-in .NET types

Why Was BinaryFormatter Deprecated?

Microsoft has deprecated BinaryFormatter due to security vulnerabilities, such as:

  • Remote Code Execution (RCE): Deserializing untrusted data can execute arbitrary code.

  • Data Integrity Issues: Attackers can manipulate serialized data.

  • Compatibility Problems: Different versions of .NET may have breaking changes.

Alternatives like System.Text.Json, XmlSerializer, and MessagePack are recommended for modern applications.


How to Use BinaryFormatter for Serialization

1. Adding Required Namespaces

To use BinaryFormatter, include the necessary namespaces:

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

2. Defining a Serializable Class

A class must be marked with [Serializable] to be serialized using BinaryFormatter.

[Serializable]
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

If a class contains fields that should not be serialized, mark them with [NonSerialized]:

[Serializable]
public class Employee
{
    public string Name { get; set; }
    public int Age { get; set; }
    [NonSerialized] public string Password;
}

3. Serializing an Object to a File

Use the BinaryFormatter class to serialize an object and save it to a file:

public static void SerializeObject(string filePath, object obj)
{
    using (FileStream fs = new FileStream(filePath, FileMode.Create))
    {
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize(fs, obj);
    }
}

// Usage:
Person person = new Person { Name = "Alice", Age = 30 };
SerializeObject("person.dat", person);

4. Deserializing an Object from a File

To read a serialized object from a file:

public static object DeserializeObject(string filePath)
{
    using (FileStream fs = new FileStream(filePath, FileMode.Open))
    {
        BinaryFormatter formatter = new BinaryFormatter();
        return formatter.Deserialize(fs);
    }
}

// Usage:
Person deserializedPerson = (Person)DeserializeObject("person.dat");
Console.WriteLine($"Name: {deserializedPerson.Name}, Age: {deserializedPerson.Age}");

BinaryFormatter and Object Graphs

BinaryFormatter can serialize entire object graphs, including references between objects.

[Serializable]
public class Department
{
    public string DepartmentName { get; set; }
    public List<Employee> Employees { get; set; }
}

This allows serialization of complex objects with nested relationships:

Department dept = new Department { DepartmentName = "IT", Employees = new List<Employee> { new Employee { Name = "John", Age = 28 } } };
SerializeObject("department.dat", dept);
Department deserializedDept = (Department)DeserializeObject("department.dat");

Security Risks and Alternatives

1. Security Risks

Using BinaryFormatter can expose your application to:

  • Remote Code Execution (RCE)

  • Data Tampering

  • Type Confusion Attacks

Never deserialize untrusted data!

2. Alternative Serialization Methods

Serialization TypeUse Case
System.Text.JsonModern JSON serialization in .NET Core & .NET 5+
Newtonsoft.JsonPopular alternative for JSON serialization
XmlSerializerXML-based serialization for interoperability
MessagePackFast, efficient binary serialization

Example using System.Text.Json:

using System.Text.Json;
string json = JsonSerializer.Serialize(person);
Person personObj = JsonSerializer.Deserialize<Person>(json);

Conclusion

While BinaryFormatter was once a standard serialization method in C#, it is now deprecated due to security concerns. Understanding its usage is valuable for maintaining legacy systems, but modern applications should use safer alternatives like System.Text.Json or MessagePack.

By following best practices and using modern serialization techniques, developers can ensure secure, efficient, and maintainable data persistence strategies in C# applications.


Key Takeaways

BinaryFormatter enables binary serialization but is deprecated due to security risks.
✅ Avoid using BinaryFormatter in modern applications.
✅ Use alternatives like System.Text.Json for secure, efficient serialization.
✅ Always validate and sanitize input data to prevent security vulnerabilities.

If you're still working with BinaryFormatter in legacy projects, consider migrating to modern alternatives for improved security and performance!