Codebelt
v10.1.7

Codebelt.Extensions.Newtonsoft.Json

Extend Json.NET with reusable converters, formatter options, and queryable JSON traversal.

.NET 10.0 / .NET 9.0 / .NET Standard 2.0 MIT 16,833 downloads

Overview

Codebelt.Extensions.Newtonsoft.Json adds package-owned building blocks around Json.NET for two jobs: producing consistent JSON with preconfigured converters and contract resolvers, and traversing JSON documents as a queryable result hierarchy. The package centers those behaviors in NewtonsoftJsonFormatter, converter registration extensions, and the JData reader API.

It also exposes focused helpers for dynamic converter creation, property-name resolution, and JSON validation so you can keep custom serialization logic close to JsonSerializerSettings instead of scattering one-off wrappers throughout an application.

Key APIs

NewtonsoftJsonFormatter serializes to and from Stream using NewtonsoftJsonFormatterOptions, refreshes converter dependencies on construction, and can optionally synchronize its settings with JsonConvert.DefaultSettings.

NewtonsoftJsonFormatterOptions supplies the package defaults: indented output, camel-cased contract resolution through DynamicContractResolver.Create<CamelCasePropertyNamesContractResolver>, supported media types, and a bootstrap list of default converters for DataPair, enums, flags enums, transient faults, and failures.

JsonConverterCollectionExtensions is the main registration surface for package-owned converter behavior. It adds converters for exceptions, ExceptionDescriptor, Failure, TransientFaultException, DataPair, and string-based enum handling directly onto JsonSerializerSettings.Converters.

JData reads a JSON string, stream, or JsonReader into JDataResult nodes and preserves hierarchy so consumers can inspect arrays, nested objects, paths, CLR token types, and raw values without writing a custom traversal loop.

JDataResultExtensions adds the higher-level querying layer on top of JDataResult, including Flatten, ExtractObjectValues, and ExtractArrayValues for path-based extraction across nested JSON structures.

JsonConverterFactory creates JsonConverter implementations from delegates, including typed overloads and a wrapper overload that preserves naming-strategy behavior when an existing converter is reused under a different contract resolver.

DynamicContractResolver creates wrapped IContractResolver implementations that run package-supplied property handlers during CreateProperty, which is how the formatter options suppress properties such as delegates, MemberInfo graphs, and selected exception members.

ValidatorExtensions adds InvalidJsonDocument guards for both string and JsonReader, throwing ArgumentException when the input is not valid RFC 8259 JSON and resetting the reader to a fresh token stream when validation succeeds.

Basic usage

using System;
using System.Linq;
using Codebelt.Extensions.Newtonsoft.Json;
using Codebelt.Extensions.Newtonsoft.Json.Converters;
using Codebelt.Extensions.Newtonsoft.Json.Formatters;
using Codebelt.Extensions.Xunit;
using Newtonsoft.Json;
using Xunit;

namespace MyProject.Tests;

public class JsonDocumentWorkflowTest : Test
{
    public JsonDocumentWorkflowTest(ITestOutputHelper output) : base(output)
    {
    }

    [Fact]
    public void SerializeFlagsAndInspectTheDocument()
    {
        var settings = new NewtonsoftJsonFormatterOptions().Settings;
        settings.Converters.Clear();
        settings.Converters.AddStringFlagsEnumConverter();

        var payload = new ExportRequest("production", DeliveryChannels.Email | DeliveryChannels.Webhook);
        var json = JsonConvert.SerializeObject(payload, settings);
        var nodes = JData.ReadAll(json).Flatten().ToList();
        var environment = nodes.Single(node => node.Path == "environment");
        var channels = nodes.Single(node => node.Path == "channels" && node.Children.Count == 2)
            .Children
            .Select(node => (string)node.Value)
            .ToArray();

        TestOutput.WriteLines(
            $"Environment: {environment.Value}",
            $"Channels: {string.Join(", ", channels)}");

        Assert.Equal("production", environment.Value);
        Assert.Equal(new[] { "email", "webhook" }, channels);
    }

    [Flags]
    private enum DeliveryChannels
    {
        Email = 1,
        Webhook = 2
    }

    private sealed class ExportRequest
    {
        public ExportRequest(string environment, DeliveryChannels channels)
        {
            Environment = environment;
            Channels = channels;
        }

        public string Environment { get; }

        public DeliveryChannels Channels { get; }
    }
}

Use this pattern when you want package-owned converter registration and JSON traversal helpers to work together in the same serialization flow. It matters because the package lets you shape Json.NET output and inspect the resulting document with the same set of conventions instead of building custom converters and token walkers by hand.

Installation

dotnet add package Codebelt.Extensions.Newtonsoft.Json

Usage guidance

Adopt this package when you want Newtonsoft.Json-based applications to share formatter defaults, exception-aware converters, dynamic contract resolution, and structured JSON inspection utilities from one library. If you only need plain JsonSerializerSettings customization, native JsonConvert calls, or ASP.NET Core MVC integration, prefer raw Json.NET for the first case and the sibling ASP.NET packages in this repository for the second.

Family packages