Table of Contents

Class JsonConverterCollectionExtensions

Namespace
Codebelt.Extensions.Newtonsoft.Json.Converters
Assembly
Codebelt.Extensions.Newtonsoft.Json.dll

Extension methods for the Newtonsoft.Json.JsonConverter class.

public static class JsonConverterCollectionExtensions
Inheritance
JsonConverterCollectionExtensions

Examples

The JsonConverterCollectionExtensions class provides extension methods for registering a comprehensive set of JSON converters for enums, exceptions, transient faults, and diagnostic types. Without these converters, enum values serialize as numeric codes, exceptions lose diagnostic context, and framework-specific types produce verbose or incorrect JSON unsuitable for REST APIs and observability pipelines.

This example demonstrates the class method signature and the registration pattern used by all extension methods. You create a NewtonsoftJsonFormatter with an options callback that receives configuration action for the underlying JsonSerializerSettings. Inside that callback, you call extension methods on the settings.Converters collection to register converters. The callback is invoked once at formatter initialization, allowing you to compose multiple converter registrations in a fluent, declarative style. After the formatter is initialized with all converters registered, any JSON serialization or deserialization performed by that formatter instance will use the registered converters to handle their respective types. The result is human-readable, self-documenting JSON that REST API consumers and client libraries can immediately parse without additional type metadata. This pattern is central to ASP.NET Core integration where the formatter is registered as the application's default JSON handler:

using System;
using Codebelt.Extensions.Newtonsoft.Json.Converters;
using Cuemon.Diagnostics;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace Examples;

public enum Status { Active, Inactive, Pending }

[Flags]
public enum Permissions { Read = 1, Write = 2, Execute = 4 }

public class EnumConvertersProgram
{
    public static void Main()
    {
        var settings = new JsonSerializerSettings();
        
        // Register enum and flags converters
        settings.Converters.AddStringEnumConverter();
        var namingStrategy = new CamelCaseNamingStrategy();
        settings.Converters.AddStringFlagsEnumConverter(namingStrategy);
        
        // Register exception descriptor converter for structured error handling
        settings.Converters.AddExceptionDescriptorConverterOf<ExceptionDescriptor>(
            setup => setup.SensitivityDetails = FaultSensitivityDetails.StackTrace | FaultSensitivityDetails.Data
        );

        // Serialize data with enum and flags values
        var status = Status.Active;
        var permissions = Permissions.Read | Permissions.Write;
        var data = new { status, permissions };
        
        // Output shows enums as readable strings and flags as arrays
        var json = JsonConvert.SerializeObject(data, settings);
        Console.WriteLine($"Serialized: {json}");
        // Output: {"status":"Active","permissions":["Read","Write"]}
    }
}

Adding Exception Converters

Exception details in API responses often need to include stack traces for debugging or be scrubbed for security. Without specialized handling, exceptions serialize to verbose, implementation-specific output that leaks internal structure details and is difficult for clients to parse. The AddExceptionConverter, AddTransientFaultExceptionConverter, and AddExceptionDescriptorConverter methods provide fine-grained control over exception serialization, enabling you to include or exclude stack traces, inner exception chains, and custom data while maintaining a consistent JSON contract that clients can reliably consume. This is crucial for error handling in distributed systems, observability pipelines, and public APIs. The following example shows how to register exception and failure converters:

using System;
using Codebelt.Extensions.Newtonsoft.Json.Converters;
using Cuemon.Diagnostics;
using Newtonsoft.Json;

namespace MyApplication
{
    public class ExceptionConvertersProgram
    {
        public static void Main()
        {
            var settings = new JsonSerializerSettings();
            
            // Add exception converter with stack trace and data
            settings.Converters.AddExceptionConverter(includeStackTrace: true, includeData: true);

            // Add transient fault exception converter
            settings.Converters.AddTransientFaultExceptionConverter();

            var ex = new InvalidOperationException("Something went wrong");
            var json = JsonConvert.SerializeObject(ex, settings);
            Console.WriteLine($"Serialized: {json}");
        }
    }
}

Adding Failure Converter

Resilience patterns like Result types and Failure structs provide a functional alternative to exception throwing for representing operation outcomes. When serializing these types to JSON for inter-service communication or persistence, generic failure payloads need to be transformed into domain-specific error contracts that APIs and clients understand. The AddFailureConverter method automatically converts Failure instances (which capture operation failure reasons, codes, and metadata) into JSON objects that conform to RFC 7807 problem details or custom error contracts. This enables seamless integration of functional error handling patterns with JSON serialization and REST APIs. The following example demonstrates the failure converter for resilience patterns:

using System;
using Codebelt.Extensions.Newtonsoft.Json.Converters;
using Newtonsoft.Json;

namespace Examples;

public class FailureConverterProgram
{
    public static void Main()
    {
        var settings = new JsonSerializerSettings();
        settings.Converters.AddFailureConverter();
        settings.Converters.AddExceptionConverter(includeStackTrace: false, includeData: false);

        // When a failure result is created, it will serialize using the registered converter
        var exceptionData = new { error = "Request failed due to timeout", statusCode = 408 };
        var json = JsonConvert.SerializeObject(exceptionData, settings);
        Console.WriteLine($"Serialized: {json}");
    }
}

Adding Data Pair Converter

Diagnostic metadata—logs, request correlation IDs, custom attributes, performance metrics—are often represented as key-value pairs or tuples in the application code. Serializing diagnostic context to JSON without a converter forces manual mapping to intermediate objects or requires custom serialization logic. The AddDataPairConverter method automatically serializes diagnostic data pairs into compact, queryable JSON objects that can be aggregated and searched in logging systems and observability platforms. This is essential for applications that generate rich diagnostic context and need to serialize it efficiently alongside exception details and application state. The following example demonstrates serializing diagnostic data pairs:

using System;
using System.Collections.Generic;
using Codebelt.Extensions.Newtonsoft.Json.Converters;
using Newtonsoft.Json;

namespace Examples;

public class DataPairConverterProgram
{
    public static void Main()
    {
        var settings = new JsonSerializerSettings();
        settings.Converters.AddDataPairConverter();

        // Diagnostic context is captured as structured data
        var diagnosticData = new Dictionary<string, object>
        {
            { "UserId", 12345 },
            { "RequestId", "req-789" },
            { "Environment", "production" }
        };

        var json = JsonConvert.SerializeObject(diagnosticData, settings);
        Console.WriteLine($"Serialized: {json}");
    }
}

These extension methods provide fluent, chainable registration of converters and follow the receiver pattern, allowing seamless integration with the Newtonsoft.Json serialization pipeline.

Methods

AddDataPairConverter(ICollection<JsonConverter>)

Adds an DataPair JSON converter to the list.

public static ICollection<JsonConverter> AddDataPairConverter(this ICollection<JsonConverter> converters)

Parameters

converters ICollection<JsonConverter>

The ICollection{JsonConverter} to extend.

Returns

ICollection<JsonConverter>

A reference to converters after the operation has completed.

AddExceptionConverter(ICollection<JsonConverter>, bool, bool)

Adds an Exception JSON converter to the list.

public static ICollection<JsonConverter> AddExceptionConverter(this ICollection<JsonConverter> converters, bool includeStackTrace, bool includeData)

Parameters

converters ICollection<JsonConverter>

The ICollection{JsonConverter} to extend.

includeStackTrace bool

The value that determine whether the stack of an exception is included in the converted result.

includeData bool

The value that determine whether the data of an exception is included in the converted result.

Returns

ICollection<JsonConverter>

A reference to converters after the operation has completed.

AddExceptionDescriptorConverterOf<T>(ICollection<JsonConverter>, Action<ExceptionDescriptorOptions>, Action<JsonWriter, T, JsonSerializer>, Action<JsonWriter, T, JsonSerializer>)

Adds an ExceptionDescriptor JSON converter to the list.

public static ICollection<JsonConverter> AddExceptionDescriptorConverterOf<T>(this ICollection<JsonConverter> converters, Action<ExceptionDescriptorOptions> setup = null, Action<JsonWriter, T, JsonSerializer> afterWriteErrorStartObject = null, Action<JsonWriter, T, JsonSerializer> beforeWriteEndObject = null) where T : ExceptionDescriptor

Parameters

converters ICollection<JsonConverter>

The ICollection{JsonConverter} to extend.

setup Action<ExceptionDescriptorOptions>

The ExceptionDescriptorOptions which may be configured.

afterWriteErrorStartObject Action<JsonWriter, T, JsonSerializer>

The delegate that is invoked just after writing JSON start object (Error).

beforeWriteEndObject Action<JsonWriter, T, JsonSerializer>

The delegate that is invoked just before writing the JSON end object.

Returns

ICollection<JsonConverter>

A reference to converters after the operation has completed.

Type Parameters

T

AddFailureConverter(ICollection<JsonConverter>)

Adds a Failure JSON converter to the list.

public static ICollection<JsonConverter> AddFailureConverter(this ICollection<JsonConverter> converters)

Parameters

converters ICollection<JsonConverter>

The ICollection{JsonConverter} to extend.

Returns

ICollection<JsonConverter>

A reference to converters after the operation has completed.

AddStringEnumConverter(ICollection<JsonConverter>, NamingStrategy)

Adds an Enum JSON converter to the list.

public static ICollection<JsonConverter> AddStringEnumConverter(this ICollection<JsonConverter> converters, NamingStrategy ns = null)

Parameters

converters ICollection<JsonConverter>

The ICollection{JsonConverter} to extend.

ns NamingStrategy

The optional Newtonsoft.Json.Serialization.NamingStrategy to apply.

Returns

ICollection<JsonConverter>

A reference to converters after the operation has completed.

AddStringFlagsEnumConverter(ICollection<JsonConverter>, NamingStrategy)

Adds a combined Enum and FlagsAttribute JSON converter to the list.

public static ICollection<JsonConverter> AddStringFlagsEnumConverter(this ICollection<JsonConverter> converters, NamingStrategy ns = null)

Parameters

converters ICollection<JsonConverter>

The ICollection{JsonConverter} to extend.

ns NamingStrategy

The optional Newtonsoft.Json.Serialization.NamingStrategy to apply.

Returns

ICollection<JsonConverter>

A reference to converters after the operation has completed.

AddTransientFaultExceptionConverter(ICollection<JsonConverter>)

Adds an TransientFaultException JSON converter to the list.

public static ICollection<JsonConverter> AddTransientFaultExceptionConverter(this ICollection<JsonConverter> converters)

Parameters

converters ICollection<JsonConverter>

The ICollection{JsonConverter} to extend.

Returns

ICollection<JsonConverter>

A reference to converters after the operation has completed.