SergeiM.Json 0.2.0

dotnet add package SergeiM.Json --version 0.2.0
                    
NuGet\Install-Package SergeiM.Json -Version 0.2.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="SergeiM.Json" Version="0.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SergeiM.Json" Version="0.2.0" />
                    
Directory.Packages.props
<PackageReference Include="SergeiM.Json" />
                    
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 SergeiM.Json --version 0.2.0
                    
#r "nuget: SergeiM.Json, 0.2.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 SergeiM.Json@0.2.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=SergeiM.Json&version=0.2.0
                    
Install as a Cake Addin
#tool nuget:?package=SergeiM.Json&version=0.2.0
                    
Install as a Cake Tool

SergeiM.Json

GitHub Actions Workflow Status NuGet Hits-of-Code GitHub License

Immutable JSON library for .NET inspired by Jakarta JSON API (JSR 374). This library provides a clean, fluent API for working with JSON data structures using immutable types.

Features

  • Immutable JSON Types: All JSON values (objects, arrays, strings, numbers, booleans, null) are immutable
  • Builder Pattern: Fluent API for constructing JSON objects and arrays
  • Type-Safe Accessors: Strongly-typed methods for accessing JSON values with optional defaults
  • JSON Pointer (RFC 6901): Navigate JSON structures using JSON Pointer syntax
  • JSON Patch (RFC 6902): Apply modifications to JSON documents with Add, Remove, Replace, Move, Copy, and Test operations
  • Stream-Based I/O: Efficient reading and writing of JSON from/to streams
  • Modern .NET: Built for .NET 8+ with full nullable reference type support

Installation

dotnet add package SergeiM.Json

Quick Start

Creating JSON Objects

using SergeiM.Json;

// Using builder pattern
var person = new JsonObjectBuilder()
    .Add("name", "Alice")
    .Add("age", 30)
    .Add("isActive", true)
    .Add("address", new JsonObjectBuilder()
        .Add("city", "New York")
        .Add("zip", "10001"))
    .Build();

// Accessing values
string name = person.GetString("name");           // "Alice"
int age = person.GetInt("age");                   // 30
bool active = person.GetBoolean("isActive");      // true

// With defaults for missing keys
int score = person.GetInt("score", 0);            // 0 (key doesn't exist)

Creating JSON Arrays

// Using builder pattern
var numbers = new JsonArrayBuilder()
    .Add(1)
    .Add(2)
    .Add(3)
    .Build();

// Accessing elements
int first = numbers.GetInt(0);                    // 1
int count = numbers.Count;                        // 3

// Iteration
foreach (JsonValue value in numbers)
{
    Console.WriteLine(value);
}

Reading and Writing JSON

// Reading from string
var reader = new JsonReader(new StringReader(jsonString));
JsonValue value = reader.Read();
JsonObject obj = reader.ReadObject();
JsonArray arr = reader.ReadArray();

// Reading from stream
using var fileStream = File.OpenRead("data.json");
var streamReader = new JsonReader(new StreamReader(fileStream));
var data = streamReader.ReadObject();

// Writing to string
var writer = new JsonWriter(new StringWriter());
writer.Write(person);
string json = stringWriter.ToString();

// Writing with formatting
var options = new JsonWriterOptions { IndentOutput = true };
var prettyWriter = new JsonWriter(new StringWriter(), options);
prettyWriter.WriteObject(person);

// Writing Unicode characters without escaping (Cyrillic, Chinese, etc.)
var unicodeWriter = new JsonWriter(new StringWriter(), JsonWriterOptions.UnicodeUnescaped);
unicodeWriter.Write(new JsonString("Привет мир")); // Writes: "Привет мир" (not "\u041F...")

// Pretty print with Unicode
var prettyUnicode = new JsonWriter(new StringWriter(), JsonWriterOptions.PrettyPrintUnicodeUnescaped);

JSON Pointer (RFC 6901)

var doc = new JsonObjectBuilder()
    .Add("users", new JsonArrayBuilder()
        .Add(new JsonObjectBuilder()
            .Add("name", "Alice")
            .Add("email", "alice@example.com")))
    .Build();

// Navigate using JSON Pointer
var pointer = new JsonPointer("/users/0/email");
JsonValue email = pointer.GetValue(doc);          // "alice@example.com"

// Check existence
bool exists = pointer.Contains(doc);              // true

// Safe access
if (pointer.TryGetValue(doc, out var value))
{
    Console.WriteLine(value);
}

// Building pointers
var newPointer = JsonPointer.Empty
    .Append("users")
    .Append("0")
    .Append("name");                              // "/users/0/name"

JSON Patch (RFC 6902)

var original = new JsonObjectBuilder()
    .Add("name", "Alice")
    .Add("age", 30)
    .Build();

// Apply patch operations
var patch = new JsonPatch(
    JsonPatchOperation.Add("/email", new JsonString("alice@example.com")),
    JsonPatchOperation.Replace("/age", new JsonNumber(31)),
    JsonPatchOperation.Remove("/name")
);

JsonValue modified = patch.Apply(original);

// Test operation (throws if value doesn't match)
var testPatch = new JsonPatch(
    JsonPatchOperation.Test("/age", new JsonNumber(30)),
    JsonPatchOperation.Add("/verified", JsonValue.True)
);

// Move operation
var movePatch = new JsonPatch(
    JsonPatchOperation.Move("/oldName", "/name")
);

// Copy operation
var copyPatch = new JsonPatch(
    JsonPatchOperation.Copy("/template", "/instance")
);

API Overview

Core Types

  • JsonValue: Base class for all JSON values
  • JsonObject: Immutable JSON object (key-value pairs)
  • JsonArray: Immutable JSON array (ordered list)
  • JsonString: JSON string value
  • JsonNumber: JSON number value (supports int, long, double, decimal)
  • JsonBoolean: JSON boolean value (true/false)
  • JsonNull: JSON null value (singleton)

Builders

  • JsonObjectBuilder: Fluent builder for creating JSON objects
  • JsonArrayBuilder: Fluent builder for creating JSON arrays

I/O

  • JsonReader: Read JSON from streams or TextReader
  • JsonWriter: Write JSON to streams or TextWriter
  • JsonReaderOptions: Configuration for JSON parsing (comments, trailing commas)
  • JsonWriterOptions: Configuration for JSON output (indentation, formatting, Unicode escaping)
    • Default: Compact output with Unicode escaping
    • PrettyPrint: Indented output with Unicode escaping
    • UnicodeUnescaped: Compact output without Unicode escaping (for Cyrillic, Chinese, etc.)
    • PrettyPrintUnicodeUnescaped: Indented output without Unicode escaping

JSON Pointer & Patch

  • JsonPointer: Navigate JSON structures using RFC 6901 pointer syntax
  • JsonPatch: Apply modifications using RFC 6902 patch operations
  • JsonPatchOperation: Individual patch operations (Add, Remove, Replace, Move, Copy, Test)

Type Conversions

var number = new JsonNumber(42);

int intValue = number.IntValue();
long longValue = number.LongValue();
double doubleValue = number.DoubleValue();
decimal decimalValue = number.DecimalValue();

Immutability

All JSON types are immutable. Operations that appear to modify a JSON structure actually return a new instance:

var original = new JsonObjectBuilder()
    .Add("x", 10)
    .Build();

// This creates a NEW JsonObject, original is unchanged
var modified = Json.CreateObjectBuilder(original)
    .Add("y", 20)
    .Build();

Console.WriteLine(original.ContainsKey("y"));     // false
Console.WriteLine(modified.ContainsKey("y"));     // true

Error Handling

// Accessing non-existent keys
try
{
    int value = obj.GetInt("missing");            // Throws KeyNotFoundException
}
catch (KeyNotFoundException) { }

// Use defaults to avoid exceptions
int value = obj.GetInt("missing", 0);             // Returns 0

// Invalid JSON
try
{
    var reader = JsonReader.Create(new StringReader("invalid"));
    var value = reader.Read();                    // Throws JsonException
}
catch (JsonException ex) { }

// Failed patch operations
try
{
    var patch = new JsonPatch(
        JsonPatchOperation.Test("/value", new JsonNumber(99))
    );
    patch.Apply(doc);               // Throws JsonException if test fails
}
catch (JsonException ex) { }
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 (1)

Showing the top 1 NuGet packages that depend on SergeiM.Json:

Package Downloads
SergeiM.Http

A fluent HTTP client library for .NET that provides a pure OOP approach to building and executing HTTP requests with method chaining. Supports wire decorators for authorization, retries, and custom request handling.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.0 201 1/31/2026
0.1.0 162 12/28/2025
0.0.2 166 12/20/2025
0.0.1 132 12/20/2025