Linh.JsonKit 2.0.0

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

README.md (Hoàn thiện - Tiếng Anh)

Linh.JsonKit

Linh.JsonKit is a powerful, flexible, and high-performance .NET toolkit for working with JSON. It is built on top of System.Text.Json and enhanced with features inspired by Newtonsoft.Json and the performance of SpanJson to provide a comprehensive solution for serializing, deserializing, and querying JSON data.

✨ Key Features

  • JConvert - Intelligent Serialization & Deserialization:
    • A simple and familiar API, inspired by Newtonsoft's JsonConvert.
    • Supports multiple naming conventions: PascalCase, camelCase, snake_case, and kebab-case.
    • Highly flexible customization via the "options pattern," allowing fine-grained control.
    • Smartly handles reference loops with Throw, Ignore, or Preserve options.
    • Flexible enum handling: Deserializes from strings or numbers, and allows serializing as strings or numbers.
    • Automatically converts dynamic and Dictionary<string, object> to native .NET types without intermediate JsonElement objects.
    • Includes high-performance extension methods powered by SpanJson for critical hot paths.
  • JPath - Powerful JSON Queries:
    • Query JsonElement and JsonNode structures using a simple path syntax (e.g., data.users[0].name).
    • High-performance, zero-allocation path parsing powered by ReadOnlySpan<char>.
    • Supports positive and negative array indexing (e.g., [-1] for the last element).
    • Provides a type-safe (TryGetValueByPath) and flexible (SelectNode, SelectElement) API.

🚀 Installation

Install Linh.JsonKit via the NuGet Package Manager.

dotnet add package Linh.JsonKit

Or via the Package Manager Console:

Install-Package Linh.JsonKit

📚 How to Use

1. JConvert - Serialization and Deserialization

Simply add using Linh.JsonKit; and using Linh.JsonKit.Enums; to get access to the powerful extension methods and configuration enums.

Serialize an Object to a JSON String

Basic Usage:

var user = new { FirstName = "Linh", LastName = "Nguyen", IsActive = true };
string json = user.ToJson();
// Output: {"FirstName":"Linh","LastName":"Nguyen","IsActive":true}

Customizing Serialization:

Use the options pattern to configure naming conventions, indentation, and enum serialization.

public enum UserStatus { Inactive, Active }
var userWithStatus = new { Name = "Linh", Status = UserStatus.Active };

string customizedJson = userWithStatus.ToJson(options =>
{
    options.NamingConvention = NamingConvention.CamelCase;
    options.EnumSerialization = EnumSerializationMode.AsString; // Serialize enum as "Active"
    options.WriteIndented = true;
});

/* Output:
{
  "name": "Linh",
  "status": "Active"
}
*/

Advanced Customization:

Access the underlying System.Text.Json options for more control.

var product = new { ProductName = "Super Gadget", Price = 99.95m };

string advancedJson = product.ToJson(options =>
{
    options.NamingConvention = NamingConvention.KebabCaseLower;
    options.SystemTextJsonOptions.NumberHandling = JsonNumberHandling.WriteAsString;
});
// Output: {"product-name":"Super Gadget","price":"99.95"}
Deserialize a JSON String to an Object

Use the FromJson<T>() extension method.

Basic Deserialization:

By default, deserialization is case-insensitive.

public record User(string FirstName, string LastName);

string json = @"{ ""firstName"": ""Linh"", ""lastName"": ""Nguyen"" }";
User? user = json.FromJson<User>();

Console.WriteLine(user?.FirstName); // Output: Linh

Flexible Enum Deserialization:

The built-in enum converter intelligently handles strings (case-insensitive names or numbers) and integer values without extra configuration.

public record UserWithStatus(string Name, UserStatus Status);

// All of these will deserialize correctly to UserStatus.Active
"{\"Name\":\"Test\", \"Status\":\"Active\"}".FromJson<UserWithStatus>();
"{\"Name\":\"Test\", \"Status\":1}".FromJson<UserWithStatus>();
"{\"Name\":\"Test\", \"Status\":\"1\"}".FromJson<UserWithStatus>();
High-Performance SpanJson Helpers

For maximum performance in hot paths, use the built-in extension methods powered by SpanJson.

Note: These methods use a separate SpanJson pipeline and do not apply the options (like NamingConvention) configured for the main ToJson method.

var user = new { FirstName = "Linh", LastName = "Nguyen" };

// Serialize
byte[] utf8Bytes = user.ToJsonUtf8Bytes();
string utf16String = user.ToJsonUtf16();

// Deserialize
var userFromBytes = utf8Bytes.FromJsonUtf8<User>();

2. JPath - JSON Queries

JPath allows you to access deeply nested values within JsonElement or JsonNode safely and efficiently.

Setup:

var json = """
{
  "store": {
    "books": [
      { "title": "The Hitchhiker's Guide", "price": 12.50 },
      { "title": "Ready Player One", "price": 15.99 }
    ],
    "owner": { "name": "Linh" }
  }
}
""";
var rootElement = JsonDocument.Parse(json).RootElement;

Get a Value with TryGetValueByPath:

This is the safest way to extract data. It returns true if the value is found and successfully converted.

// Get a string value from a nested object
if (rootElement.TryGetValueByPath("store.owner.name", out string? ownerName))
{
    Console.WriteLine($"Owner: {ownerName}"); // Output: Owner: Linh
}

// Get a numeric value from an array using a negative index
if (rootElement.TryGetValueByPath("store.books[-1].price", out decimal price))
{
    Console.WriteLine($"Last book price: {price}"); // Output: Last book price: 15.99
}

// A non-existent path will safely return false
if (!rootElement.TryGetValueByPath("store.manager.name", out string? managerName))
{
    Console.WriteLine("Manager not found."); // Output: Manager not found.
}

Select a Node/Element with SelectElement:

Use this if you need a subsection of the JSON tree for further processing.

// Select a child object
JsonElement? ownerElement = rootElement.SelectElement("store.owner");
if (ownerElement.HasValue)
{
    // You can use JConvert to re-serialize the selected part
    Console.WriteLine(ownerElement.Value.ToJson(o => o.WriteIndented = true));
    /* Output:
     {
       "name": "Linh"
     }
    */
}

🏛️ Architecture & Performance Notes

Linh.JsonKit is designed with performance and flexibility in mind.

  • Optimized Caching: JConvert pre-builds and caches JsonSerializerOptions instances for common configurations. This significantly speeds up repeated serialization tasks.

  • Safe Customization: When you provide custom configurations, JConvert creates a safe, temporary copy of the cached settings. This guarantees thread-safety and prevents "read-only" errors in multi-threaded or benchmark scenarios.

  • Zero-Allocation Path Parsing: JPath uses ReadOnlySpan<char> and ref struct parsers to navigate JSON paths without allocating memory on the managed heap, making it extremely efficient for querying tasks.

❤️ Contributing

Contributions are always welcome! If you have ideas, suggestions, or find a bug, please open an issue or create a pull request.


Made with ❤️ by Linh Nguyen.

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.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Linh.JsonKit:

Package Downloads
Linh.CodeEngine

A powerful .NET 8 library for compiling and executing C# code dynamically at runtime. This engine supports loading modules from strings or files, managing them with different lifetimes (Singleton, Scoped, Transient), and provides a ready-to-use API controller for easy integration into ASP.NET Core applications. It's designed for building extensible systems like plugin platforms or dynamic rule engines.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0 108 7/17/2025
1.0.6 123 6/27/2025
1.0.5 132 6/24/2025
1.0.4 142 6/23/2025