CodeGym /Kurse /C# SELF /Wir besprechen BinaryForma...

Wir besprechen BinaryFormatter

C# SELF
Level 44, Lektion 1
Verfügbar

1. Einleitung

In vielen alten Lehrbüchern und Beispielen zu C# findet man Serialisierung mit der Klasse BinaryFormatter. Früher war das Standard: praktisch, schnell, weniger Aufwand. Ein Beispiel aus alten Zeiten sah ungefähr so aus:

// Gefährlicher alter Code! Nicht so in neuen Projekten verwenden!
var bf = new BinaryFormatter();
using (var stream = File.Open("player.dat", FileMode.Create))
{
    bf.Serialize(stream, playerObject);
}

In modernem .NET 9 könnt ihr solchen Code nicht mal mehr kompilieren: BinaryFormatter wurde aus der Plattform entfernt.

Vom Helden zum Ausgestoßenen

Ursprünglich war BinaryFormatter als universeller Mechanismus zur Serialisierung und Deserialisierung von .NET‑Objekten gedacht, der komplexe Objektgraphen „wie sie sind“ speichern kann. Mit der Zeit traten jedoch gravierende Sicherheits‑ und Kompatibilitätsprobleme zutage, und inzwischen gehört er der Vergangenheit an — ungefähr wie Kassettenrekorder in der Streaming‑Ära.

2. Hauptgründe für die Abkehr von BinaryFormatter

Riesiges Sicherheitsloch

BinaryFormatter kann nicht nur Daten serialisieren, sondern auch Typen aus dem Eingabestrom rekonstruieren. Wenn man unüberlegte Deserialisierung von nicht vertrauenswürdigen Daten macht (z. B. aus dem Netzwerk), kann ein Angreifer eine Nutzlast einschleusen, die zur Remote‑Code‑Ausführung (RCE) führt. Genau deshalb hat Microsoft über viele Jahre gewarnt: „Verwendet nicht BinaryFormatter“. Ab .NET 5 wurde es als veraltet und gefährlich markiert ([Obsolete]), und in .NET 9 wurde es entfernt.

Abhängigkeit von der internen Klassenstruktur

Das Format von BinaryFormatter zieht Implementierungsdetails der Typen nach sich: Felder, Packing, Versionen. Kleinste Änderungen in Klassen (Feld hinzugefügt/entfernt) brechen die Kompatibilität mit bereits gespeicherten Dateien. Das macht das Format ungeeignet für langfristige Speicherung und versionsübergreifenden Austausch.

Probleme mit Cross‑Plattform

Daten, die mit BinaryFormatter gespeichert wurden, sind an die interne Repräsentation von .NET‑Objekten gebunden. Sie auf einer anderen Plattform/Sprache oder sogar in einer anderen .NET‑Version zu lesen ist oft unmöglich.

3. Wie man alten Code findet und was zu tun ist

Anzeichen für die Nutzung von BinaryFormatter sehen so aus:

using System.Runtime.Serialization.Formatters.Binary; // <-- verdächtig!
BinaryFormatter bf = new BinaryFormatter();           // <-- gefährlich!
bf.Serialize(...);
bf.Deserialize(...);

In modernen .NET‑Versionen kompiliert solcher Code nicht: die Tools melden einen Fehler wie "Typ oder Name nicht gefunden". In Legacy‑Projekten unter .NET Framework gibt es mindestens strenge Warnungen.

Wenn ihr auf solchen Code stoßt, ersetzt BinaryFormatter durch moderne, sichere Alternativen.

Welche Formate und Klassen heute verwenden?

Für JSON

  • System.Text.Json — schnell, sicher, in .NET eingebaut. Offizielle Dokumentation
  • Newtonsoft.Json — beliebte Drittanbieter‑Bibliothek für komplexe Fälle.

Für XML

Für binäre Formate

  • System.Formats.Cbor (CBOR)
  • Protobuf.Net (Protocol Buffers), MessagePack for C#

Für spezifische Aufgaben wählt man spezialisierte Formate und Bibliotheken — einen „universellen“ binären Serializer im Stil von BinaryFormatter gibt es nicht mehr, und das ist gut so.

4. Code neu schreiben statt BinaryFormatter

Wofür man BinaryFormatter nicht verwenden darf

Nicht verwenden:

  • Benutzereinstellungen und wichtige Daten speichern.
  • Daten über das Netzwerk senden (Client ↔ Server).
  • Daten aus nicht verifizierten Quellen deserialisieren.

Stattdessen:

  • Für den Alltag — System.Text.Json.
  • Für Konfigurationen — JSON, XML usw.
  • Für sprachübergreifenden Austausch — Formate mit plattformübergreifender Kompatibilität (JSON, XML, Protobuf, MessagePack).

Welche Art von Code jetzt schreiben?

JSON‑Serialisierung (empfohlener Weg)

using System.Text.Json;
// Ihr Klasse:
public class Player
{
    public string Name { get; set; } = "";
    public int Health { get; set; }
    public bool IsAlive { get; set; }
}

// Objekt zur Serialisierung
var player = new Player { Name = "Aragorn", Health = 100, IsAlive = true };

// Objekt in JSON‑String umwandeln
string json = JsonSerializer.Serialize(player);

// In Datei speichern — sicher!
File.WriteAllText("player.json", json);

// Objekt aus Datei wiederherstellen:
string loadedJson = File.ReadAllText("player.json");
Player loadedPlayer = JsonSerializer.Deserialize<Player>(loadedJson)!;

XML‑Serialisierung (wenn ein striktes Format nötig ist)

using System.Xml.Serialization;
// Die Klasse muss einen öffentlichen parameterlosen Konstruktor haben

var player = new Player { Name = "Aragorn", Health = 100, IsAlive = true };
var serializer = new XmlSerializer(typeof(Player));
using (var fs = File.Create("player.xml"))
{
    serializer.Serialize(fs, player);
}

Visuelles Schema „alt vs neu“

Aufgabe Alter Weg (BinaryFormatter) Moderner Weg
Serialisierung in Datei
bf.Serialize(stream, obj)
JsonSerializer.Serialize(...)
XmlSerializer.Serialize(...)
Deserialisierung aus Datei
bf.Deserialize(stream)
JsonSerializer.Deserialize<T>(...)
XmlSerializer.Deserialize(...)
Sicherheit Angreifbar (RCE) Sichere Parser und strikte Modelle
Cross‑Plattform Nein Ja (JSON/XML/Protobuf)
Geschwindigkeit Schnell, aber gefährlich Schnell und sicher

5. Typische Fehler bei der Arbeit mit XmlSerializer

Fehler Nr. 1: private Properties oder Felder. XmlSerializer serialisiert nur public Properties; sogar protected führt zu Problemen.

Fehler Nr. 2: Fehlender Standardkonstruktor. Ein öffentlicher parameterloser Konstruktor ist nötig, sonst klappt die Serialisierung/Deserialisierung nicht.

Fehler Nr. 3: Typeninkompatibilität. XmlSerializer arbeitet schlecht mit Dictionary, interface und delegate — benutzt Wrapper oder andere Formate.

Fehler Nr. 4: Zyklische Referenzen (circular reference). XmlSerializer unterstützt keine Graphen wie A → B → A; für solche Fälle nimmt man meist JSON mit passenden Einstellungen.

2
Aufgabe
C# SELF, Level 44, Lektion 1
Gesperrt
Vergleich der Serialisierung von JSON und XML für ein einfaches Objekt
Vergleich der Serialisierung von JSON und XML für ein einfaches Objekt
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION