Codezerg.BinarySerialization 1.1.0

dotnet add package Codezerg.BinarySerialization --version 1.1.0
                    
NuGet\Install-Package Codezerg.BinarySerialization -Version 1.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Codezerg.BinarySerialization" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Codezerg.BinarySerialization" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Codezerg.BinarySerialization" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Codezerg.BinarySerialization --version 1.1.0
                    
#r "nuget: Codezerg.BinarySerialization, 1.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Codezerg.BinarySerialization@1.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Codezerg.BinarySerialization&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Codezerg.BinarySerialization&version=1.1.0
                    
Install as a Cake Tool

Codezerg.BinarySerialization

NuGet License: MIT .NET

A high-performance .NET binary serialization library featuring key interning, struct templates, and streaming support. Designed for memory efficiency with embedded commands that allow in-stream definitions.

Features

  • Compact Format - Single-byte type markers with optimized encoding for small values
  • Key Interning - Repeated map keys are stored once and referenced by ID (30%+ space savings)
  • Struct Templates - Define object shapes once, reuse for multiple instances
  • Streaming Support - Unbounded arrays and maps for streaming scenarios
  • DoS Protection - Built-in limits for table sizes, string lengths, and nesting depth
  • Zero Dependencies - Pure .NET with no external dependencies

Installation

dotnet add package Codezerg.BinarySerialization

Quick Start

using Codezerg.BinarySerialization;

// Define your class
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public bool IsActive { get; set; }
}

// Serialize
var person = new Person { Name = "Alice", Age = 30, IsActive = true };
byte[] bytes = BinarySerializer.Serialize(person);

// Deserialize
var restored = BinarySerializer.Deserialize<Person>(bytes);

Low-Level API

using Codezerg.BinarySerialization;

// Write data
using var stream = new MemoryStream();
using var writer = new BinarySerializationWriter(stream, leaveOpen: true);

writer.WriteMapHeader(2);
writer.Write("name");
writer.Write("Alice");
writer.Write("age");
writer.Write(30);
writer.Flush();

// Read data
stream.Position = 0;
using var reader = new BinarySerializationReader(stream);

var count = reader.ReadMapHeader();
for (int i = 0; i < count; i++)
{
    var key = reader.ReadString();
    var type = reader.PeekType();

    if (type == SerializedType.String)
        Console.WriteLine($"{key}: {reader.ReadString()}");
    else if (type == SerializedType.Integer)
        Console.WriteLine($"{key}: {reader.ReadInt32()}");
}

High-Level Serialization

Attributes

Control serialization with attributes:

public class User
{
    [BinaryProperty("user_name")]  // Custom serialized name
    public string Name { get; set; }

    [BinaryProperty(Order = 1)]    // Control serialization order
    public int Id { get; set; }

    [BinaryIgnore]                  // Exclude from serialization
    public string PasswordHash { get; set; }
}

Supported Types

The high-level API supports:

  • Primitives: bool, byte, sbyte, short, ushort, int, uint, long, ulong, float, double, decimal
  • Strings and byte[]
  • DateTime, DateTimeOffset, TimeSpan, Guid
  • Enums
  • Nullable types
  • Collections: Arrays, List<T>, Dictionary<TKey, TValue>
  • Dynamic: Dictionary<string, object>, List<object> (values read by serialized type)
  • DataTable, DataSet, and IDataReader
  • Nested objects

Options

var options = new SerializerOptions
{
    UseKeyInterning = true,   // Enable key interning (default: true)
    IncludeFields = false     // Include public fields (default: false)
};

var bytes = BinarySerializer.Serialize(obj, options);

DataTable, DataSet, and IDataReader

Serialize ADO.NET data structures directly:

// DataTable serialization
var table = new DataTable();
table.Columns.Add("Id", typeof(int));
table.Columns.Add("Name", typeof(string));
table.Rows.Add(1, "Alice");
table.Rows.Add(2, "Bob");

byte[] bytes = BinarySerializer.Serialize(table);
var restored = BinarySerializer.Deserialize<DataTable>(bytes);

// DataSet serialization
var dataSet = new DataSet();
dataSet.Tables.Add(table);
byte[] dsBytes = BinarySerializer.Serialize(dataSet);
var restoredDs = BinarySerializer.Deserialize<DataSet>(dsBytes);

// IDataReader serialization (e.g., from DbCommand.ExecuteReader())
using var reader = command.ExecuteReader();
byte[] readerBytes = BinarySerializer.Serialize<IDataReader>(reader);
var tableFromReader = BinarySerializer.Deserialize<DataTable>(readerBytes);

Format: DataTable/IDataReader is serialized as an array of row dictionaries [{col: val, ...}, ...], and DataSet as an array of DataTables. This compact format supports List<> and Dictionary<,> as column values. IDataReader uses streaming format since row count is unknown upfront.

Key Interning

Reduce payload size by interning repeated map keys:

using var writer = new BinarySerializationWriter(stream);

writer.WriteArrayHeader(1000);
for (int i = 0; i < 1000; i++)
{
    writer.WriteMapHeader(3);
    writer.WriteKey("username");  // Stored once, referenced 999 times
    writer.Write($"user{i}");
    writer.WriteKey("email");     // Same - huge space savings!
    writer.Write($"user{i}@example.com");
    writer.WriteKey("active");
    writer.Write(i % 2 == 0);
}

Result: ~32% smaller payload compared to writing keys as full strings every time.

Struct Templates

For highly repetitive object structures, define a template once:

using var writer = new BinarySerializationWriter(stream);

// Define struct template (keys stored once)
var personStruct = writer.DefineStruct("name", "age", "city");

// Write instances - only values are serialized!
writer.UseStruct(personStruct);
writer.Write("Alice");
writer.Write(30);
writer.Write("New York");

writer.UseStruct(personStruct);
writer.Write("Bob");
writer.Write(25);
writer.Write("London");

Streaming Collections

Use unbounded collections when you don't know the size upfront:

using var writer = new BinarySerializationWriter(stream);

writer.BeginArray();  // Start unbounded array

// Write items as they arrive
foreach (var item in GetStreamingData())
{
    writer.Write(item);
}

writer.WriteEnd();  // End the array

Reading unbounded collections:

using var reader = new BinarySerializationReader(stream);

var length = reader.ReadArrayHeader();  // Returns -1 for unbounded

while (!reader.IsEnd())
{
    var value = reader.ReadString();
    Console.WriteLine(value);
}
reader.ReadEnd();

Supported Types

Type Methods
Null WriteNil()
Boolean Write(bool), ReadBoolean()
Integers Write(sbyte/byte/short/ushort/int/uint/long/ulong), ReadInt32(), ReadInt64(), ReadUInt64()
Floats Write(float/double), ReadSingle(), ReadDouble()
Strings Write(string), ReadString()
Binary Write(byte[]), Write(ReadOnlySpan<byte>), ReadBinary()
Arrays WriteArrayHeader(count), BeginArray(), ReadArrayHeader()
Maps WriteMapHeader(count), BeginMap(), ReadMapHeader()

Security

Configure reader limits to prevent DoS attacks:

var limits = new ReaderLimits
{
    MaxStringLength = 1_000_000,      // 1MB max string
    MaxBinaryLength = 10_000_000,     // 10MB max binary
    MaxKeyTableSize = 1000,           // Max interned keys
    MaxStructTableSize = 100,         // Max struct templates
    MaxDepth = 50                     // Max nesting depth
};

using var reader = new BinarySerializationReader(stream, limits: limits);

Binary Format

The format uses a single-byte type marker system:

Range Description
0x00-0x7F Positive fixint (0-127)
0x80-0x8F Fixmap (0-15 pairs)
0x90-0x9F Fixarray (0-15 elements)
0xA0-0xBF Fixstr (0-31 bytes)
0xC0-0xD6 Extended types (nil, bool, numbers, strings, collections)
0xE0-0xEF Negative fixint (-16 to -1)
0xF0-0xFF Commands (SET_KEY, USE_KEY, DEFINE_STRUCT, etc.)

See docs/serialization_format_specification.md for the complete specification.

Building

# Build
dotnet build

# Run tests
dotnet test

# Run examples
dotnet run --project examples/Codezerg.BinarySerialization.Examples

# Create NuGet package
dotnet pack -c Release

License

MIT License - see LICENSE for details.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.0 93 1/13/2026
1.0.0 96 1/13/2026