CSharpEssentials.Json 6.5.2

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

CSharpEssentials.Json

Enhanced JSON serialization utilities on top of System.Text.Json.

Features

  • Enum Conventions: [StringEnum] enums read and write their wire names (AddEnumConventions); other enums keep the host's behavior.
  • Multi-Format DateTime: Read DateTime and DateTime? from many date formats automatically.
  • Polymorphic Serialization: Serialize abstract types and interfaces with a $type discriminator.
  • Pre-Configured Options: CamelCase, ignore cycles, ignore nulls, relaxed escaping, plus a strict preset.
  • JsonElement Helpers: ToClrObject turns a JsonElement into plain CLR values.

Installation

dotnet add package CSharpEssentials.Json

Targets net11.0, net10.0, net9.0 and netstandard2.1. It depends on CSharpEssentials.Enums.

Usage

Pre-Configured Options

using CSharpEssentials.Json;
using System.Text.Json;

var options = EnhancedJsonSerializerOptions.DefaultOptions;
string json = JsonSerializer.Serialize(myObject, options);
Member Contents
DefaultOptionsWithoutConverters Web defaults, camelCase, case-insensitive reads, nulls ignored on write, ReferenceHandler.IgnoreCycles, relaxed escaping
DefaultOptions The above plus enum conventions (Data mode), MultiFormatDateTimeConverterFactory and PolymorphicJsonConverterFactory
DefaultOptionsWithDateTimeConverter DefaultOptionsWithoutConverters plus MultiFormatDateTimeConverterFactory
StrictOptions Case-sensitive; rejects trailing commas, comments and unmapped members
CreateOptionsWithConverters(params JsonConverter[]) DefaultOptionsWithoutConverters plus the given converters
options.Create(configure) Copies the options and applies configure to the copy
source.ApplyTo(target) / target.ApplyFrom(source) Copies settings and converters onto another instance; the target keeps its own TypeInfoResolver when the source has none

The preset instances are shared and become read-only after first use, so call Create to get a modifiable copy. EnhancedJsonSerializerOptions is annotated [RequiresUnreferencedCode] and [RequiresDynamicCode] because DefaultOptions includes the reflection-based polymorphic converter.

JsonSerializerOptions indented = EnhancedJsonSerializerOptions.DefaultOptions.Create(o => o.WriteIndented = true);

var target = new JsonSerializerOptions();
EnhancedJsonSerializerOptions.DefaultOptions.ApplyTo(target);

Quick Extensions

ConvertToJson, ConvertFromJson and ConvertToJsonDocument<T> use EnhancedJsonSerializerOptions.DefaultOptions (or the options you pass) through reflection-based serialization. They are annotated [RequiresUnreferencedCode] and [RequiresDynamicCode]; in trimmed or NativeAOT apps call JsonSerializer with a JsonSerializerContext instead.

using System.Text.Json;
using CSharpEssentials.Json;

var user = new User("Alice", 30);

string json = user.ConvertToJson();                    // {"name":"Alice","age":30}
User? parsed = json.ConvertFromJson<User>();
object? untyped = json.ConvertFromJson(typeof(User));
JsonDocument doc = json.ConvertToJsonDocument();

public record User(string Name, int Age);

ConvertToJsonDocument() on a string takes no options: it parses the text as JSON, and text that is not valid JSON becomes a JSON string value in the document. It returns null only when every strategy fails. ConvertToJsonDocument<T>(options) on any other value serializes it to a document.

JsonElement to CLR Values

Dictionary<string, object> and object deserialize to JsonElement. ToClrObject turns them into plain values: objects become Dictionary<string, object?>, arrays List<object?>, numbers int, long, decimal or double (first that fits).

using System.Text.Json;
using CSharpEssentials.Json;

using JsonDocument doc = JsonDocument.Parse("""{"id":1,"price":9.99,"tags":["a"]}""");

var data = (Dictionary<string, object?>)doc.RootElement.ToClrObject()!;
// data["id"] is int, data["price"] is decimal, data["tags"] is List<object?>

Enum Conventions

AddEnumConventions adds the enum converter for every enum with generated metadata ([StringEnum], see CSharpEssentials.Enums). Other enums are left to the converters already on the options, so a plain enum stays a number unless you add JsonStringEnumConverter yourself.

using System.Text.Json;
using CSharpEssentials.Enums;
using CSharpEssentials.Json;

[StringEnum]
public enum Status { Active, Inactive, [EnumFallback] Unknown }

public enum Level { Low, High }

public sealed record Account(Status Status, Level Level);

// Data mode (the default): tolerant, for values you stored or received from a trusted service
JsonSerializerOptions data = new JsonSerializerOptions(JsonSerializerDefaults.Web)
    .AddEnumConventions(EnumConventions.Default);

// Input mode: strict, for request bodies (AddEnumConventions() in CSharpEssentials.AspNetCore does this for you)
JsonSerializerOptions input = new JsonSerializerOptions(JsonSerializerDefaults.Web)
    .AddEnumConventions(EnumConventions.Default, EnumReadMode.Input);

JsonSerializer.Serialize(new Account(Status.Active, Level.High), data); // {"status":"active","level":1}
JsonSerializer.Deserialize<Account>("""{"status":"gone","level":0}""", data);  // Status.Unknown (fallback)
JsonSerializer.Deserialize<Account>("""{"status":"gone","level":0}""", input); // throws EnumValueJsonException
  • Reads accept the wire name, the member name in any casing, aliases and the number of a defined member. Input mode applies EnumConventions.AcceptNumbers, AcceptMemberNames and CaseInsensitive.
  • Undefined values ("gone", 999) are rejected with EnumValueJsonException (a JsonException whose Error property carries the EnumValueError). In Data mode only, they map to the [EnumFallback] member when the enum declares one (EnumConventions.UnknownValue = UnknownEnumValueHandling.UseFallback, the default).
  • Writes are the wire name, or the number with writeAs: EnumWireFormat.Number. [Flags] values are JSON arrays.
  • EnhancedJsonSerializerOptions.DefaultOptions already calls AddEnumConventions(EnumConventions.Default) (Data mode).
  • A [StringEnum] enum without generated metadata (CSE0015) throws when its converter is created instead of falling back to numbers. AddEnumConventionsWithReflection also converts enums without metadata through reflection; it is not trim or AOT safe.

ConditionalStringEnumConverter (4.x) is obsolete and forwards to the same converter in Input mode. It no longer has AllowUndefinedValues: undefined numbers are always rejected. See Migrating from 4.x to 5.0.

StringEnumNaming

StringEnumNaming is obsolete in 5.0 and stays as a working facade over EnumMetadata. In new code use EnumMetadata, EnumValueFormatter, EnumValueParser or the generated ToWireName() and TryParseWire helpers: they are the naming source that JSON, EF Core storage, Swagger schemas and query/route binding all use, so a member is spelled the same everywhere. Names are [JsonStringEnumMemberName] when present, otherwise snake_case_lower.

using CSharpEssentials.Enums;
using CSharpEssentials.Json;

[StringEnum]
public enum Http { OK, HTTPStatus }

StringEnumNaming.GetName(Http.HTTPStatus);                    // "http_status"
StringEnumNaming.GetNames<Http>();                            // ["ok", "http_status"]
StringEnumNaming.TryParse<Http>("HTTPStatus", out var value); // true (policy name, member name or number)

Polymorphic Serialization

namespace Zoo;

public abstract class Animal { public string Name { get; set; } = string.Empty; }
public class Dog : Animal { public string Breed { get; set; } = string.Empty; }
using Zoo;

Animal dog = new Dog { Name = "Rex", Breed = "Labrador" };
string json = dog.ConvertToJson(); // {"$type":"Zoo.Dog","breed":"Labrador","name":"Rex"}

Animal? restored = json.ConvertFromJson<Animal>();

DefaultOptions applies PolymorphicJsonConverterFactory to abstract classes and interfaces; collections and dictionaries keep the built-in array and object serialization. The $type value is the concrete type's full name (namespace included) and is written first. On read, $type is required and is matched against the non-abstract types of the loaded assemblies that derive from the declared type; a missing or unknown value throws JsonException. Discovery uses reflection, so this is not trim or AOT safe: use [JsonPolymorphic] with source generation there.

Multi-Format DateTime

MultiFormatDateTimeConverterFactory (part of DefaultOptions and DefaultOptionsWithDateTimeConverter) reads DateTime and DateTime? from JSON strings in ISO 8601 (with or without Z or an offset), yyyy-MM-dd, dd.MM.yyyy, dd/MM/yyyy, MM/dd/yyyy, March 14, 2024, 14 March 2024, yyyyMMdd, RFC 1123 (Thu, 14 Mar 2024 15:30:45 GMT) and other patterns, and from a numeric string of Unix seconds. Unrecognized text throws JsonException listing the supported formats; null is allowed only for DateTime?. Values are written as yyyy-MM-ddTHH:mm:ss.ffffffzzz.

string[] dates = ["\"2024-03-14T15:30:45Z\"", "\"14.03.2024\"", "\"March 14, 2024\""];
foreach (var d in dates)
{
    DateTime dt = d.ConvertFromJson<DateTime>();
}

var options = new JsonSerializerOptions();
options.Converters.Add(new MultiFormatDateTimeConverterFactory("dd.MM.yyyy HH-mm"));
DateTime custom = JsonSerializer.Deserialize<DateTime>("\"14.03.2024 10-20\"", options);

Constructor arguments add formats to the built-in list. Every value is returned as UTC (DateTime.Kind is Utc) regardless of the host time zone: input without an offset is read as UTC, input with an offset or Z is converted to UTC, and a Unix-seconds string becomes the matching UTC instant. A date-only value such as "14.03.2024" is midnight UTC on that date. Slash dates are tried as dd/MM/yyyy before MM/dd/yyyy, so "03/04/2024" reads as 3 April.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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.  net11.0 is compatible. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (7)

Showing the top 5 NuGet packages that depend on CSharpEssentials.Json:

Package Downloads
CSharpEssentials.Results

Result pattern implementation for functional error handling in C#. Provides Result<T> and Result types for railway-oriented programming, eliminating exceptions for expected failures. Foundation for functional programming patterns and robust error handling.

CSharpEssentials

A comprehensive C# library enhancing functional programming capabilities with type-safe monads (Maybe, Result), discriminated unions (Any), and robust error handling. Features include: domain-driven design support, enhanced Entity Framework integration, testable time management, JSON utilities, and LINQ extensions. Built for modern C# development with focus on maintainability, testability, and functional programming principles.

CSharpEssentials.EntityFrameworkCore

Enhances Entity Framework Core with functional programming patterns and DDD-friendly features. Includes base entity classes, soft delete support, audit trails, query filters, optimistic concurrency, PostgreSQL integration, query performance monitoring, and domain event handling. Perfect for building maintainable and scalable data access layers in modern .NET applications.

CSharpEssentials.AspNetCore

A comprehensive ASP.NET Core library that enhances functional programming capabilities in web applications. Features include API versioning, global exception handling with enhanced problem details, enum binding and wire formats, model validation, optimized JSON handling, and seamless integration with CSharpEssentials core functional patterns (Result, Maybe, Rule Engine). Perfect for building robust, maintainable, and type-safe web APIs following functional programming principles. OpenAPI documents come from CSharpEssentials.AspNetCore.OpenApi or CSharpEssentials.AspNetCore.Swashbuckle.

CSharpEssentials.Any

Discriminated union types (Any<T0,T1> to Any<T0,...,T7>) for functional programming in C#. Provides type-safe alternatives to object/dynamic with pattern matching, implicit conversions, and JSON serialization support. Essential for functional programming patterns and type-safe handling of multiple possible types.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
6.5.2 320 10/10/2026
6.5.1 327 10/10/2026
6.5.0 322 10/9/2026
6.4.0 341 10/9/2026
6.3.0 354 10/8/2026
6.2.0 409 10/8/2026
6.1.0 409 10/7/2026
6.0.0 425 10/7/2026
5.2.1 433 10/7/2026
5.2.0 444 10/7/2026
5.1.0 463 10/7/2026
5.0.0 475 10/6/2026
4.1.0 456 10/6/2026
4.0.0 460 10/5/2026
3.2.3 622 5/31/2026
3.2.2 510 5/31/2026
3.2.1 486 5/31/2026
3.2.0 482 5/30/2026
3.1.0 475 5/27/2026
3.0.8 458 5/20/2026
Loading failed