ToonNet.AspNetCore 2.0.0

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

ToonNet.AspNetCore

ASP.NET Core integration for ToonNet serialization

.NET NuGet Downloads Status


๐Ÿ“ฆ What is ToonNet.AspNetCore?

ToonNet.AspNetCore provides seamless integration of ToonNet serialization with ASP.NET Core:

  • โœ… Dependency Injection - Register ToonEncoder and options
  • โœ… Configuration Binding - Load settings from appsettings.json
  • โœ… Options Validation - Fail-fast on invalid configuration
  • โœ… TOON Configuration Provider - Read TOON files as configuration source
  • โœ… MVC Ready - Foundation for the ToonNet.AspNetCore.Mvc formatters

Perfect for:

  • ๐ŸŒ Web APIs - Shared options for TOON responses (formatters in ToonNet.AspNetCore.Mvc)
  • โš™๏ธ Configuration - Load TOON config files
  • ๐Ÿ”ง DI Integration - Inject ToonEncoder and options into services
  • ๐Ÿ“Š Options Pattern - Configure ToonNet via appsettings.json

๐Ÿš€ Quick Start

Installation

# Core package (required)
dotnet add package ToonNet.Core

# ASP.NET Core integration
dotnet add package ToonNet.AspNetCore

# For MVC formatters (optional)
dotnet add package ToonNet.AspNetCore.Mvc

Basic Setup - Default Options

using ToonNet.AspNetCore.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

// Register ToonNet services with default options
builder.Services.AddToonNet();

var app = builder.Build();
app.Run();

This registers:

  • ToonEncoder (singleton)
  • ToonOptions (IOptions<ToonOptions>)
  • ToonSerializerOptions (IOptions<ToonSerializerOptions>)

โš™๏ธ Configuration

appsettings.json:

{
  "ToonNet": {
    "ToonOptions": {
      "IndentSize": 2,
      "MaxDepth": 100,
      "Delimiter": ",",
      "StrictMode": true,
      "AllowExtendedLimits": false
    },
    "ToonSerializerOptions": {
      "IncludeReadOnlyProperties": false,
      "MaxDepth": 100,
      "AllowExtendedLimits": false
    }
  }
}

Only the keys shown in the tables below are read. ToonSerializerOptions also accepts IgnoreNullValues and PropertyNamingPolicy (Default, CamelCase, SnakeCase, LowerCase). Use a different root section name with AddToonNet(builder.Configuration, "MySection").

Program.cs:

using ToonNet.AspNetCore.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

// Bind configuration from appsettings.json
builder.Services.AddToonNet(builder.Configuration);

var app = builder.Build();
app.Run();

Using Delegate Configuration

builder.Services.AddToonNet(toonOptions =>
{
    toonOptions.IndentSize = 4;
    toonOptions.MaxDepth = 50;
}, serializerOptions =>
{
    serializerOptions.IncludeReadOnlyProperties = false;
    serializerOptions.MaxDepth = 100;
});

Hybrid Approach (Configuration + Delegate)

// Load from config, then override specific values (Configure runs after the configuration binding)
builder.Services.AddToonNet(builder.Configuration);

builder.Services.Configure<ToonOptions>(toonOptions =>
{
    toonOptions.IndentSize = 4;
});

builder.Services.Configure<ToonSerializerOptions>(serializerOptions =>
{
    serializerOptions.IncludeReadOnlyProperties = true;
});

๐Ÿ“– Configuration Options

ToonOptions

Controls TOON format encoding behavior:

Option Type Default Description
IndentSize int 2 Number of spaces per indentation level (even, 2-100)
MaxDepth int 100 Maximum nesting depth when encoding and parsing; deeper input is rejected with ToonParseException
Delimiter char , Document delimiter: ,, tab or \| (configuration also accepts comma, tab, pipe)
StrictMode bool true Enable strict parsing rules (e.g. array length checks)
AllowExtendedLimits bool false Allow MaxDepth above 200 (up to 1000)

ToonSerializerOptions

Controls C# object serialization behavior:

Option Type Default Description
IgnoreNullValues bool false Skip properties whose value is null
IncludeReadOnlyProperties bool true Include read-only properties when serializing
PropertyNamingPolicy PropertyNamingPolicy Default Key naming: Default, CamelCase, SnakeCase, LowerCase
MaxDepth int 100 Maximum object graph depth
AllowExtendedLimits bool false Allow MaxDepth above 200 (up to 1000)

Untrusted input: parsing enforces ToonOptions.MaxDepth and also checks the remaining stack space, so hostile, deeply nested input fails with a ToonParseException instead of crashing the process. Keep AllowExtendedLimits off for input you don't control.


๐ŸŽฏ Usage Patterns

Pattern 1: Inject ToonEncoder

ToonEncoder is registered as a singleton with the configured ToonOptions. There is no injectable parser; parse with ToonDocument.Parse and the injected options:

using Microsoft.Extensions.Options;
using ToonNet.Core;
using ToonNet.Core.Encoding;
using ToonNet.Core.Models;

public class ToonService
{
    private readonly ToonEncoder _encoder;
    private readonly ToonOptions _options;
    private readonly ILogger<ToonService> _logger;

    public ToonService(
        ToonEncoder encoder,
        IOptions<ToonOptions> options,
        ILogger<ToonService> logger)
    {
        _encoder = encoder;
        _options = options.Value;
        _logger = logger;
    }

    public ToonDocument ParseToon(string toonString)
    {
        try
        {
            return ToonDocument.Parse(toonString, _options);
        }
        catch (ToonParseException ex)
        {
            _logger.LogError(ex, "Failed to parse TOON");
            throw;
        }
    }

    public string EncodeToon(ToonDocument document)
    {
        return _encoder.Encode(document);
    }
}

// Register service
builder.Services.AddScoped<ToonService>();

Pattern 2: Inject Options

using Microsoft.Extensions.Options;
using ToonNet.Core;
using ToonNet.Core.Serialization;

public class ConfigAnalyzer
{
    private readonly ToonOptions _toonOptions;
    private readonly ToonSerializerOptions _serializerOptions;

    public ConfigAnalyzer(
        IOptions<ToonOptions> toonOptions,
        IOptions<ToonSerializerOptions> serializerOptions)
    {
        _toonOptions = toonOptions.Value;
        _serializerOptions = serializerOptions.Value;
    }

    public void LogConfiguration()
    {
        Console.WriteLine($"Indent Size: {_toonOptions.IndentSize}");
        Console.WriteLine($"Max Depth: {_toonOptions.MaxDepth}");
        Console.WriteLine($"Include Read-Only: {_serializerOptions.IncludeReadOnlyProperties}");
    }
}

Pattern 3: Use with ToonSerializer

using ToonNet.Core.Serialization;
using Microsoft.Extensions.Options;

public class DataService
{
    private readonly ToonSerializerOptions _options;

    public DataService(IOptions<ToonSerializerOptions> options)
    {
        _options = options.Value;
    }

    public string SerializeData<T>(T data)
    {
        // Use configured options
        return ToonSerializer.Serialize(data, _options);
    }

    public T DeserializeData<T>(string toonString)
    {
        return ToonSerializer.Deserialize<T>(toonString, _options);
    }
}

๐Ÿ“‚ TOON Configuration Provider

Load TOON files as ASP.NET Core configuration sources:

Create TOON Configuration File

appsettings.toon:

Database:
  ConnectionString: Server=localhost;Database=mydb
  Timeout: 30
  EnableRetry: true

Logging:
  Level: Information
  Console:
    Enabled: true
  File:
    Path: logs/app.log
    MaxSize: 10485760

Features:
  EnableCache: true
  CacheExpiry: 3600

Register TOON Configuration Provider

var builder = WebApplication.CreateBuilder(args);

// Add TOON file as configuration source (using ToonNet.AspNetCore.Configuration;)
builder.Configuration.AddToonFile("appsettings.toon", optional: false, reloadOnChange: true);

// Register ToonNet services
builder.Services.AddToonNet(builder.Configuration);

var app = builder.Build();

// Access configuration
var connectionString = builder.Configuration["Database:ConnectionString"];
var logLevel = builder.Configuration["Logging:Level"];

Configuration Provider Features

// Multiple TOON files
builder.Configuration
    .AddToonFile("appsettings.toon")
    .AddToonFile($"appsettings.{builder.Environment.EnvironmentName}.toon", optional: true);

// With environment variables
builder.Configuration
    .AddToonFile("config.toon")
    .AddEnvironmentVariables();

// Reload on change
builder.Configuration.AddToonFile(
    "settings.toon",
    optional: false,
    reloadOnChange: true  // Auto-reload when file changes
);

// Custom parsing options (e.g. non-strict mode)
builder.Configuration.AddToonFile("legacy.toon", optional: true, reloadOnChange: false,
    options: new ToonOptions { StrictMode = false });

Nested objects become Section:Key paths and array items become index keys (Items:0, Items:1). Values are stored as strings: booleans become True/False, and numbers keep their exact value in canonical TOON form (spec ยง2), so 12345678901234567890 stays as written while 1.0 becomes 1 and 1.50 becomes 1.5; quote a value (Version: "1.0") to keep its text exactly. AddToonFile accepts relative and absolute paths. A file that is not valid TOON throws a FormatException.


โœ… Validation

ToonNet.AspNetCore uses Options Validation to ensure configuration is valid:

Automatic Validation

// Validation happens at startup
builder.Services.AddToonNet(builder.Configuration);

// If configuration is invalid, app will fail to start with clear error message

Custom Validation

AddToonNet returns the IServiceCollection; add extra rules through the options builder:

builder.Services.AddToonNet(builder.Configuration);

builder.Services.AddOptions<ToonOptions>()
    .Validate(options => options.IndentSize <= 8, "IndentSize must not exceed 8")
    .ValidateOnStart();

Validation Rules (Built-in)

  • IndentSize: Must be an even number between 2 and 100
  • MaxDepth: Must be 1-200 (or 1-1000 if AllowExtendedLimits = true)
  • Delimiter: Must be comma, tab or pipe

๐Ÿ”’ Thread-Safety

  • ToonSerializer methods are safe to call concurrently across threads.
  • Shared metadata/name caches use ConcurrentDictionary for concurrent access.
  • Cache entries are created on demand and retained for the process lifetime (no eviction).
  • Do not mutate a single ToonSerializerOptions instance concurrently across threads.

Core:

Extensions:

Web Integration:

Development:


๐Ÿ“š Documentation


๐Ÿงช Testing

# Run ASP.NET Core integration tests
dotnet test tests/ToonNet.Tests --filter "FullyQualifiedName~ToonNet.Tests.AspNetCore"

๐Ÿ“‹ Requirements

  • .NET 8.0 or later
  • ASP.NET Core 8.0+
  • ToonNet.Core

๐Ÿ“„ License

MIT License - See LICENSE file for details.


๐Ÿค Contributing

Contributions welcome! Please read CONTRIBUTING.md first.


Part of the ToonNet serialization library family.

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 ToonNet.AspNetCore:

Package Downloads
ToonNet.AspNetCore.Mvc

ASP.NET Core MVC integration for ToonNet. Provides input/output formatters for TOON format support in MVC controllers and Web APIs.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0 52 10/8/2026
1.4.0 800 2/8/2026
1.3.0 156 2/4/2026
1.2.0 160 2/1/2026
1.1.0 163 1/28/2026
1.0.0 161 1/12/2026

v1.4.0: Updated to support ToonNet.Core 1.4.0 streaming features.