OneCiel.System.Dynamics.JsonExtension 0.0.2

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

OneCiel.System.Dynamics.JsonExtension

JSON serialization and deserialization extensions for OneCiel.System.Dynamics. Provides seamless System.Text.Json integration with DynamicDictionary for .NET 8 and .NET 9, including automatic JsonElement type conversion via the JsonElementValueResolver.

Installation

dotnet add package OneCiel.System.Dynamics.JsonExtension

Requirements

  • OneCiel.System.Dynamics (required dependency)
  • .NET 8.0 or later
  • .NET 9.0 or later

Features

  • JSON String Conversion: Convert DynamicDictionary to/from JSON strings
  • File Operations: Save and load JSON files asynchronously and synchronously
  • Automatic Type Conversion: JsonElement values are automatically converted to appropriate .NET types via resolver
  • JsonConverter Support: Use with System.Text.Json serializer options
  • Nested Object Support: Seamlessly handles nested objects and arrays
  • Flexible Formatting: Optional indented output for readability
  • Comment Handling: Support for JSON comments and trailing commas when parsing
  • Extensible Resolvers: Provides JsonElementValueResolver for custom JSON type handling

Quick Start

Modern Fluent API

JSON support is automatically initialized on first use. No manual setup required:

using OneCiel.System.Dynamics;

// Modern extension method - just call .ToDynamicDictionary() on any JSON string!
var dict = @"{ ""name"": ""John"" }".ToDynamicDictionary();
// JsonElementValueResolver is automatically registered

Fluent Extension Methods

This package provides intuitive string extension methods:

// Parse JSON object
var user = jsonString.ToDynamicDictionary();

// Parse JSON array
var users = jsonArrayString.ToDynamicArray();

JSON String Operations

using OneCiel.System.Dynamics;

// Create a DynamicDictionary
var dict = new DynamicDictionary
{
    { "name", "John Doe" },
    { "age", 30 },
    { "active", true }
};

// Convert to JSON string
string json = dict.ToJson();
// Output: {"name":"John Doe","age":30,"active":true}

// Parse from JSON string - Modern fluent API!
var parsed = json.ToDynamicDictionary();
string name = parsed.GetValue<string>("name"); // "John Doe"
int age = parsed.GetValue<int>("age"); // 30

File Operations

// Asynchronous save
await dict.ToJsonFileAsync("data.json");

// Asynchronous load
var loaded = await DynamicDictionaryJsonExtensions.FromJsonFileAsync("data.json");

// Synchronous operations
dict.ToJsonFile("sync.json");
var syncLoaded = DynamicDictionaryJsonExtensions.FromJsonFile("sync.json");

Nested Objects and Arrays

string json = @"
{
    ""user"": {
        ""id"": 1,
        ""name"": ""Alice"",
        ""email"": ""alice@example.com""
    },
    ""items"": [
        { ""id"": 1, ""title"": ""Item 1"" },
        { ""id"": 2, ""title"": ""Item 2"" }
    ]
}";

// Modern fluent API - beautifully simple!
var data = json.ToDynamicDictionary();

// Access nested properties
int userId = data.GetValue<int>("user.id"); // 1
string userName = data.GetValue<string>("user.name"); // "Alice"

// Access array elements
string firstItemTitle = data.GetValue<string>("items[0].title"); // "Item 1"
int secondItemId = data.GetValue<int>("items[1].id"); // 2

Using with System.Text.Json

using System.Text.Json;

// Configure JsonSerializerOptions with the converter
var options = new JsonSerializerOptions
{
    Converters = 
    { 
        new DynamicDictionaryJsonConverter()
    },
    WriteIndented = true,
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};

// Serialize
var dict = new DynamicDictionary { { "message", "Hello" } };
string json = JsonSerializer.Serialize(dict, options);

// Deserialize (automatically uses JsonElementValueResolver)
var deserialized = JsonSerializer.Deserialize<DynamicDictionary>(json, options);

Pretty Printing

var dict = new DynamicDictionary
{
    { "user", new DynamicDictionary { { "name", "Bob" }, { "age", 25 } } },
    { "items", new List<object> { "a", "b", "c" } }
};

// Indented JSON (human readable)
string prettyJson = dict.ToJson(writeIndented: true);

// Compact JSON
string compactJson = dict.ToJson(writeIndented: false);

JSON Element Value Resolver

The JsonElementValueResolver is automatically registered and provides automatic conversion of JsonElement values:

Automatic Type Conversion

When JSON data is loaded, JsonElement values are automatically converted:

JSON Type .NET Type
Object DynamicDictionary
Array object[] or DynamicDictionary[]
String string
Number decimal, long, int, or double
Boolean bool
Null null

Dynamic Member Access with Conversion

// Modern fluent API with dynamic type
string json = @"{ ""name"": ""Test"", ""count"": 42 }";
dynamic data = json.ToDynamicDictionary();

// Values are automatically converted from JsonElement
string name = data.name; // "Test" (string)
int count = data.count; // 42 (int)

Resolver Details

The JsonElementValueResolver:

  • Checks if a value is a JsonElement
  • Automatically converts JsonElement to appropriate .NET types
  • Recursively processes nested objects and arrays
  • Preserves typed arrays (all DynamicDictionary array elements)
  • Is thread-safe and global to all DynamicDictionary instances

API Reference

Extension Methods

String Conversion (Modern Fluent API)
// Parse JSON object - Extension method on string!
DynamicDictionary ToDynamicDictionary(this string json)
DynamicDictionary ToDynamicDictionary(this string json, JsonSerializerOptions options)

// Parse JSON array - Extension method on string!
DynamicDictionary[] ToDynamicArray(this string json)
DynamicDictionary[] ToDynamicArray(this string json, JsonSerializerOptions options)

// Convert to JSON string
string ToJson(this DynamicDictionary dictionary, bool writeIndented = true)
string ToJson(this DynamicDictionary dictionary, JsonSerializerOptions options)
File Operations
// Save to file asynchronously
static Task ToJsonFileAsync(this DynamicDictionary dictionary, string filePath, bool writeIndented = true)

// Save to file synchronously
static void ToJsonFile(this DynamicDictionary dictionary, string filePath, bool writeIndented = true)

// Load from file asynchronously
static Task<DynamicDictionary> FromJsonFileAsync(string filePath)

// Load from file synchronously
static DynamicDictionary FromJsonFile(string filePath)

// Initialize JSON support (called automatically)
static void InitializeJsonSupport()

JsonElementValueResolver

public class JsonElementValueResolver : IValueResolver
{
    public bool CanResolve(object value) // Returns true for JsonElement
    public object Resolve(object value) // Converts JsonElement to .NET type
}

JsonConverter Class

public class DynamicDictionaryJsonConverter : JsonConverter<DynamicDictionary>
{
    public override bool CanConvert(Type typeToConvert)
    public override DynamicDictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    public override void Write(Utf8JsonWriter writer, DynamicDictionary value, JsonSerializerOptions options)
}

Supported JSON Types

JSON Type .NET Type Example
Object DynamicDictionary {"key":"value"}
Array object[] or DynamicDictionary[] [1, 2, 3]
String string "text"
Number decimal, long, int, or double 123, 123.45
Boolean bool true, false
Null null null

Error Handling

All methods provide proper error handling:

try
{
    var dict = "invalid json".ToDynamicDictionary();
}
catch (InvalidOperationException ex)
{
    Console.WriteLine("JSON parsing failed: " + ex.Message);
}

try
{
    await dict.ToJsonFileAsync("/invalid/path/file.json");
}
catch (InvalidOperationException ex)
{
    Console.WriteLine("File write failed: " + ex.Message);
}

Advanced: Custom JSON Resolvers

You can also create custom value resolvers for special JSON handling:

public class CustomJsonResolver : IValueResolver
{
    public bool CanResolve(object value)
    {
        return value is MySpecialJsonType;
    }

    public object Resolve(object value)
    {
        var special = (MySpecialJsonType)value;
        // Custom transformation logic
        return TransformToDesiredType(special);
    }
}

// Register for use alongside JsonElementValueResolver
DynamicDictionary.RegisterValueResolver(new CustomJsonResolver());

License

MIT License

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 is compatible.  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 is compatible.  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.

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
0.0.2 165 11/25/2025
0.0.1 253 11/21/2025

Initial release of JSON extension for OneCiel.System.Dynamics.