CodeGym /Courses /C# SELF /Overview of standard serialization classes in .NET

Overview of standard serialization classes in .NET

C# SELF
Level 44 , Lesson 0
Available

1. Introduction

Since we decided to "disassemble a LEGO figure into parts", let's figure out what tools we have in .NET for that. In other words — which standard classes help serialize and deserialize objects into different formats and what's behind each of them.

How the .NET serialization family is organized

At the moment (2025) .NET offers several main approaches to serialization, each with its own set of classes and tools. The main and most commonly encountered ones:

  • JSON serialization — the main and most modern option, used in most projects.
  • XML serialization — a bit old-fashioned, but still actively used.
  • Binary serialization — only for special cases and usually via modern third-party solutions.

Many examples and the majority of code in .NET 9 use JSON, and that's not a fad — it's an industry standard. But .NET supports other ways too — just in case.

Main players of .NET serialization

Format Serialization class Ease Performance Security Relevance
JSON
System.Text.Json
🔥🔥🔥 🔥🔥🔥 🔥🔥🔥 Most relevant
XML
System.Xml.Serialization.XmlSerializer
🔥🔥 🔥🔥 🔥🔥 Used
JSON Newtonsoft.Json (Json.NET) 🔥🔥🔥 🔥🔥 🔥🔥🔥 Very popular

Short about each

  • System.Text.Json: The new standard for JSON serialization in .NET, introduced in .NET Core 3.0, became the main one in .NET 5+. Fast, lightweight, safe, built-in "out of the box" in .NET 9. Documentation
  • XmlSerializer: An old and proven option for XML serialization. Simple to use, but with limitations (for example, it requires a public class and public properties). Good for compatibility and strict data contracts. Documentation
  • Newtonsoft.Json: For a long time it was the de-facto standard for JSON serialization before System.Text.Json appeared. Often used for complex scenarios (dynamics, private properties, etc.). Documentation

Where did BinaryFormatter go?

If you see advice on the internet to use BinaryFormatter — it's probably an ancient tutorial. Don't use BinaryFormatter: it was removed from .NET 9 for security reasons. Modern binary serialization is provided by third-party solutions — for example, Protobuf or MessagePack.

2. Simple examples

Let's try serialization and deserialization in practice using our already familiar class Player from the game universe.

Prepare the class for serialization

// Player.cs
public class Player
{
    public string Name { get; set; }
    public int Health { get; set; }
    public bool IsAlive { get; set; }
    public List<string> Inventory { get; set; }
    public Position Position { get; set; }
}

public class Position
{
    public int X { get; set; }
    public int Y { get; set; }
}

a) JSON serialization and deserialization with System.Text.Json

using System.Text.Json;

Player aragorn = new Player
{
    Name = "Aragorn",
    Health = 100,
    IsAlive = true,
    Inventory = new List<string> { "sword", "bow", "healing potion" },
    Position = new Position { X = 10, Y = 25 }
};

// Serialize the Player object to a JSON string
string json = JsonSerializer.Serialize(aragorn);
// Print JSON to the screen
Console.WriteLine(json);

// Deserialize the JSON string back to a Player object
Player? aragornClone = JsonSerializer.Deserialize<Player>(json);
// Check that the clone works :)
Console.WriteLine(aragornClone?.Name); // Should print "Aragorn"

It's that simple — no "dance with a tambourine" or magical attributes. Now — how it looks in XML.

b) XML serialization and deserialization with XmlSerializer

using System.Xml.Serialization;

// Configure the serializer for the Player class
XmlSerializer serializer = new XmlSerializer(typeof(Player));

// Serialize to a file
using FileStream fs = new FileStream("aragorn.xml", FileMode.Create);
serializer.Serialize(fs, aragorn); // Save Aragorn to an XML file

// Deserialize from a file
using FileStream fs = new FileStream("aragorn.xml", FileMode.Open);
Player aragornFromXml = (Player) serializer.Deserialize(fs)!;
Console.WriteLine(aragornFromXml.Name); // Should print "Aragorn"

Note! XmlSerializer requires that classes and their properties are public and have a parameterless default constructor (if you override the constructor — make it public and parameterless). Otherwise serialization will fail.

c) JSON serialization and deserialization with Newtonsoft.Json

using Newtonsoft.Json; // Don't forget to add the Newtonsoft.Json package via NuGet!

// Serialization
string json2 = JsonConvert.SerializeObject(aragorn);

// Deserialization
Player? aragornFromNewtonsoft = JsonConvert.DeserializeObject<Player>(json2);

Console.WriteLine(aragornFromNewtonsoft?.Name); // Again "Aragorn"

Looks almost the same, but Newtonsoft.Json has many extra options — for example, you can serialize private fields, customize formatting and handle non-trivial scenarios.

4. Useful nuances

Standard serializers and their capabilities

Class Format Built into .NET Requires NuGet package? Good for files Good for APIs Ease
System.Text.Json
JSON Yes No Yes Yes Lightweight
Newtonsoft.Json
JSON No Yes Yes Yes Lightweight
XmlSerializer
XML Yes No Yes Often Lightweight

How to decide which class to use?

If you don't know why you need XML — almost always choose JSON and System.Text.Json. It's faster, simpler and matches modern practices.

Choose XML if:

  • You're integrating with legacy systems that require XML.
  • You need a strict schema and validation of the data structure.
  • Structures are large, stable and formal compatibility matters (settings, configs, exchange with enterprise systems).

Choose JSON if:

  • You're building a modern app interacting with web and mobile clients.
  • You need simplicity, readability and compactness.
  • You don't want to pull in extra dependencies.

Choose Newtonsoft.Json if:

  • You need serialization of private fields, special customizations, full flexibility.
  • Or the project already inherited this library and migration is not practical right now.

5. Common mistakes and pitfalls

Encoding. The main serialization classes (especially when working with files) use UTF-8 by default. If you see garbled characters, check how you're reading/writing files and the explicit encoding settings. Documentation on encoding configuration.

Unsupported types. Some standard serializers (especially XML) can't serialize, for example, dictionaries (Dictionary), private/protected fields, events, delegates and interfaces. Usually public simple properties and classes are supported.

Class versions. If you change class structure (added/renamed/removed properties), old saved data may not read or may deserialize incorrectly. Plan for format versioning.

Null values. When deserializing, if some field is missing in the data, the corresponding property will get the default value (for reference types — null). Don't forget to add checks.

Attributes. For precise control people often use attributes like [JsonIgnore], [XmlElement] and others. They let you exclude properties, change element names and manage format — details in following lectures.

2
Task
C# SELF, level 44, lesson 0
Locked
Saving and Loading an Object in XML
Saving and Loading an Object in XML
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION