Overview
Cuemon.Extensions.Text.Json extends System.Text.Json with a Cuemon-aware formatter pipeline, converter registration helpers, and small authoring primitives for custom converters. It is the package that turns Cuemon fault objects such as ExceptionDescriptor, Failure, TransientFaultException, and DataPair into JSON contracts while still letting consumers stay on JsonSerializerOptions and Utf8JsonWriter instead of moving to a separate serializer stack.
It builds on Cuemon's formatter abstractions rather than replacing the framework serializer. JsonFormatter keeps serialization stream-based, JsonFormatterOptions boots a consistent option set and media type list, and the converter extensions fill gaps such as configurable DateTime formatting, naming-policy-aware enums, and delegate-driven converters.
Key APIs
JsonFormatter serializes and deserializes arbitrary object graphs through StreamFormatter<JsonFormatterOptions>, writing with the configured JsonSerializerOptions and reading with matching reader settings for comments, trailing commas, and maximum depth.
JsonFormatterOptions starts with camelCase property naming, relaxed escaping, ignored nulls, cycle protection, and JSON media types, then registers default converters for DataPair, enums, flags enums, transient faults, and failures. Its SensitivityDetails setting also drives the exception and exception-descriptor converters that JsonFormatter adds on first use.
JsonConverterCollectionExtensions.AddExceptionDescriptorConverterOf<T> serializes ExceptionDescriptor and derived types into an error object, can include failure, stack, data, and evidence based on FaultSensitivityDetails, and exposes callbacks for adding fields around the generated payload.
JsonConverterCollectionExtensions.AddDateTimeConverter adds explicit format-string and culture-aware DateTime serialization, which is useful when a service must keep an existing timestamp contract instead of accepting the framework default.
JsonConverterCollectionExtensions.AddStringEnumConverter keeps ordinary enums aligned with the active naming policy and falls back to the built-in JsonStringEnumConverter when the internal enum factory is unavailable.
JsonConverterCollectionExtensions.AddStringFlagsEnumConverter writes [Flags] enums as JSON arrays and reconstructs the combined enum value when reading, which matches the multi-value shapes exercised in the tests.
DynamicJsonConverter.Create builds either a typed JsonConverter<T> or a JsonConverterFactory from delegates, so callers can add a focused converter without creating a dedicated converter class.
JsonSerializerOptionsExtensions.Clone and SetPropertyName, together with Utf8JsonWriterExtensions.WriteObject, support hand-written converter code by cloning serializer settings, applying the active naming policy, and serializing nested values through the current options.
Basic usage
using System;
using System.IO;
using Codebelt.Extensions.Xunit;
using Cuemon.Diagnostics;
using Cuemon.Extensions.Text.Json.Converters;
using Cuemon.Extensions.Text.Json.Formatters;
using Xunit;
namespace MyProject.Tests;
public class ExceptionDescriptorJsonTest : Test
{
public ExceptionDescriptorJsonTest(ITestOutputHelper output) : base(output)
{
}
[Fact]
public void Serialize_ShouldIncludeFailureAndEvidence()
{
var descriptor = new ExceptionDescriptor(
new InvalidOperationException("Order import aborted."),
"OrderImportFailed",
"The import request could not be completed.");
descriptor.AddEvidence("CorrelationId", Guid.Empty, correlationId => correlationId.ToString("N"));
var options = new JsonFormatterOptions { SensitivityDetails = FaultSensitivityDetails.Failure | FaultSensitivityDetails.Evidence };
options.Settings.Converters.AddExceptionDescriptorConverterOf<ExceptionDescriptor>(
o => o.SensitivityDetails = FaultSensitivityDetails.Failure | FaultSensitivityDetails.Evidence);
var formatter = new JsonFormatter(options);
using var stream = formatter.Serialize(descriptor, typeof(ExceptionDescriptor));
using var reader = new StreamReader(stream);
var json = reader.ReadToEnd();
Assert.Contains("\"error\":", json);
Assert.Contains("\"code\": \"OrderImportFailed\"", json);
Assert.Contains("\"failure\":", json);
Assert.Contains("\"correlationId\": \"00000000000000000000000000000000\"", json);
TestOutput.WriteLine(json);
}
}
Use this pattern when a service needs to publish a stable error contract from ExceptionDescriptor while still letting System.Text.Json own the wire format. It matters because AddExceptionDescriptorConverterOf<T> lets one formatter configuration include Cuemon failure details and custom evidence without hand-writing a bespoke converter class.
Installation
dotnet add package Cuemon.Extensions.Text.Json
Usage guidance
Adopt this package when System.Text.Json is already your serializer and you want Cuemon's stream formatter model, custom converter composition, or built-in JSON support for Cuemon diagnostics and resilience types. If you only need plain JsonSerializerOptions with framework converters, stay on System.Text.Json; if the JSON configuration only exists for ASP.NET Core endpoints, the ASP.NET Core sibling packages integrate the same formatter concepts more directly.
Family packages
- 🌐Cuemon.AspNetCore
- 🏭Cuemon.AspNetCore.App
- 🌐Cuemon.AspNetCore.Authentication
- 🌐Cuemon.AspNetCore.Mvc
- 🌐Cuemon.AspNetCore.Razor.TagHelpers
- 📦Cuemon.Core
- 🏭Cuemon.Core.App
- 🗄️Cuemon.Data
- 🗄️Cuemon.Data.Integrity
- 🗄️Cuemon.Data.SqlClient
- 🩺Cuemon.Diagnostics
- 🌐Cuemon.Extensions.AspNetCore
- 🌐Cuemon.Extensions.AspNetCore.Authentication
- 🌐Cuemon.Extensions.AspNetCore.Mvc
- 🌐Cuemon.Extensions.AspNetCore.Mvc.Formatters.Text.Json
- 🌐Cuemon.Extensions.AspNetCore.Mvc.Formatters.Xml
- 🌐Cuemon.Extensions.AspNetCore.Mvc.RazorPages
- 🌐Cuemon.Extensions.AspNetCore.Text.Json
- 🌐Cuemon.Extensions.AspNetCore.Xml
- 📦Cuemon.Extensions.Collections.Generic
- 📦Cuemon.Extensions.Collections.Specialized
- 📦Cuemon.Extensions.Core
- 🗄️Cuemon.Extensions.Data
- 🗄️Cuemon.Extensions.Data.Integrity
- 📦Cuemon.Extensions.DependencyInjection
- 🩺Cuemon.Extensions.Diagnostics
- 🏗️Cuemon.Extensions.Hosting
- 📦Cuemon.Extensions.IO
- 📦Cuemon.Extensions.Net
- 📦Cuemon.Extensions.Reflection
- 📦Cuemon.Extensions.Runtime.Caching
- 📝Cuemon.Extensions.Text
- 📦Cuemon.Extensions.Threading
- 📦Cuemon.Extensions.Xml
- 📦Cuemon.IO
- ⚙️Cuemon.Kernel
- 📦Cuemon.Net
- 📦Cuemon.Resilience
- 📦Cuemon.Runtime.Caching
- 🔐Cuemon.Security.Cryptography
- 📦Cuemon.Threading
- 📦Cuemon.Xml