Wolfgang.Etl.Json
0.8.1
Prefix Reserved
dotnet add package Wolfgang.Etl.Json --version 0.8.1
NuGet\Install-Package Wolfgang.Etl.Json -Version 0.8.1
<PackageReference Include="Wolfgang.Etl.Json" Version="0.8.1" />
<PackageVersion Include="Wolfgang.Etl.Json" Version="0.8.1" />
<PackageReference Include="Wolfgang.Etl.Json" />
paket add Wolfgang.Etl.Json --version 0.8.1
#r "nuget: Wolfgang.Etl.Json, 0.8.1"
#:package Wolfgang.Etl.Json@0.8.1
#addin nuget:?package=Wolfgang.Etl.Json&version=0.8.1
#tool nuget:?package=Wolfgang.Etl.Json&version=0.8.1
Wolfgang.Etl.Json
Extractors and Loaders for reading and writing JSON, JSONL, and multi-stream JSON files, built on Wolfgang.Etl.Abstractions.
📦 Installation
dotnet add package Wolfgang.Etl.Json
NuGet Package: Wolfgang.Etl.Json
✨ Features
| Component | Description |
|---|---|
JsonSingleStreamExtractor |
Extracts items from a JSON array ([{...},{...}]) in a single stream |
JsonSingleStreamLoader |
Writes items as a JSON array to a single stream |
JsonMultiStreamExtractor |
Extracts one item per stream (e.g., one JSON object per file) |
JsonMultiStreamLoader |
Writes one item per stream, with stream creation driven by item properties |
JsonLineExtractor |
Extracts items from JSONL/NDJSON (one JSON object per line) |
JsonLineLoader |
Writes items as JSONL/NDJSON (one JSON object per line) |
All components support:
System.Text.Jsonserialization with optionalJsonSerializerOptionsILogger<T>for structured diagnostic logging at Debug, Information, Warning, and Error levelsSkipItemCountandMaximumItemCountfor pagination- Progress reporting via
IProgress<TProgress>with configurableReportingInterval - Cancellation via
CancellationToken
🚀 Quick Start
Extract from a JSON array
using var stream = File.OpenRead("people.json");
var extractor = new JsonSingleStreamExtractor<Person>(stream, logger);
await foreach (var person in extractor.ExtractAsync(cancellationToken))
{
Console.WriteLine(person.Name);
}
Load to a JSON array
using var stream = File.Create("output.json");
var loader = new JsonSingleStreamLoader<Person>(stream, logger);
await loader.LoadAsync(items, cancellationToken);
Extract from multiple files (one object per file)
var streams = Directory.GetFiles("data/", "*.json").Select(File.OpenRead);
var extractor = new JsonMultiStreamExtractor<Person>(streams, logger);
await foreach (var person in extractor.ExtractAsync(cancellationToken))
{
Console.WriteLine(person.Name);
}
Load to multiple files (one object per file)
var loader = new JsonMultiStreamLoader<Person>
(
person => File.Create($"output/{person.Id}.json"),
logger
);
await loader.LoadAsync(items, cancellationToken);
Extract from JSONL/NDJSON
using var stream = File.OpenRead("data.jsonl");
var extractor = new JsonLineExtractor<Person>(stream, logger);
await foreach (var person in extractor.ExtractAsync(cancellationToken))
{
Console.WriteLine(person.Name);
}
Load to JSONL/NDJSON
using var stream = File.Create("output.jsonl");
var loader = new JsonLineLoader<Person>(stream, logger);
await loader.LoadAsync(items, cancellationToken);
Custom serialization options
All extractors and loaders accept an optional JsonSerializerOptions:
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
PropertyNameCaseInsensitive = true,
};
var extractor = new JsonSingleStreamExtractor<Person>(stream, options, logger);
Source generation (AOT-friendly)
All extractors and loaders accept a JsonTypeInfo<T> for reflection-free serialization:
[JsonSerializable(typeof(Person))]
internal partial class AppJsonContext : JsonSerializerContext { }
// Use the source-generated type info instead of JsonSerializerOptions
var extractor = new JsonSingleStreamExtractor<Person>(stream, AppJsonContext.Default.Person, logger);
var loader = new JsonLineLoader<Person>(stream, AppJsonContext.Default.Person, logger);
🎯 Supported Frameworks
This library targets:
- .NET Framework: 4.6.2, 4.8.1
- .NET Standard: 2.0
- .NET: 8.0, 10.0
See the NuGet package page for the authoritative per-TFM compatibility matrix.
🔍 Code Quality & Static Analysis
This project enforces strict code quality standards through 8 specialized analyzers and custom async-first rules:
Analyzers in Use
- Microsoft.CodeAnalysis.NetAnalyzers - Built-in .NET analyzers for correctness and performance
- Roslynator.Analyzers - Advanced refactoring and code quality rules
- AsyncFixer - Async/await best practices and anti-pattern detection
- Microsoft.VisualStudio.Threading.Analyzers - Thread safety and async patterns
- Microsoft.CodeAnalysis.BannedApiAnalyzers - Prevents usage of banned synchronous APIs
- Meziantou.Analyzer - Comprehensive code quality rules
- SonarAnalyzer.CSharp - Industry-standard code analysis
- Microsoft.CodeAnalysis.PublicApiAnalyzers - Tracks the public API surface to catch unintended breaking changes
Async-First Enforcement
This library uses BannedSymbols.txt to prohibit synchronous APIs:
Task.Wait(),Task.Result- UseawaitinsteadThread.Sleep()- Useawait Task.Delay()instead- Synchronous file I/O (
File.ReadAllText) - Use async versions - Synchronous stream operations - Use
ReadAsync(),WriteAsync() - Obsolete APIs (
WebClient,BinaryFormatter)
🛠️ Building from Source
Prerequisites
- .NET 10.0 SDK or later
- Optional: PowerShell Core for formatting scripts
Build Steps
# Clone the repository
git clone https://github.com/Chris-Wolfgang/ETL-Json.git
cd ETL-Json
# Restore dependencies
dotnet restore
# Build the solution
dotnet build --configuration Release
# Run tests
dotnet test --configuration Release
Code Formatting
This project uses .editorconfig and dotnet format:
dotnet format
dotnet format --verify-no-changes
Building Documentation
This project uses DocFX to generate API documentation:
# Install DocFX (one-time setup)
dotnet tool install -g docfx
# Generate API metadata and build documentation
cd docfx_project
docfx metadata # Extract API metadata from source code
docfx build # Build HTML documentation
# Documentation is generated in the docs/ folder at the repository root
The documentation is automatically built and deployed to GitHub Pages when changes are pushed to the main branch.
Local Preview:
# Serve documentation locally (with live reload)
cd docfx_project
docfx build --serve
# Open http://localhost:8080 in your browser
🔧 Advanced Usage
Compressed streams
All extractors and loaders accept any Stream, including compression wrappers — no special API is needed. Wrap the underlying stream in a GZipStream, BrotliStream, or DeflateStream and pass it to the constructor.
See docs/COMPRESSED-STREAMS.md for examples and a TFM compatibility table.
Schema customization
Customize JSON serialization without modifying — or even owning — the POCO class: use naming policies, DefaultJsonTypeInfoResolver modifiers (.NET 8+), custom converters, or source-generated JsonTypeInfo<T> for AOT-safe serialization.
See docs/SCHEMA-CUSTOMIZATION.md for recipes.
🔍 Verify the Build
The NuGet packages published from this repository are reproducible and
supply-chain-verified. See docs/REPRODUCIBLE-BUILD.md
for step-by-step instructions to independently reproduce and verify any
release artifact.
🤝 Contributing
Contributions are welcome! Please see CONTRIBUTING.md for:
- Code quality standards
- Build and test instructions
- Pull request guidelines
- Analyzer configuration details
📄 License
This project is licensed under the MIT License. See the LICENSE file for details.
📚 Documentation
- GitHub Repository: https://github.com/Chris-Wolfgang/ETL-Json
- API Documentation: https://Chris-Wolfgang.github.io/ETL-Json/
- Contributing Guide: CONTRIBUTING.md
| Product | Versions 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 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 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 is compatible. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.6.2
- Microsoft.Bcl.AsyncInterfaces (>= 10.0.11)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.11)
- System.Diagnostics.DiagnosticSource (>= 10.0.11)
- System.Text.Json (>= 10.0.11)
- Wolfgang.Etl.Abstractions (>= 0.23.2)
-
.NETFramework 4.8.1
- Microsoft.Bcl.AsyncInterfaces (>= 10.0.11)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.11)
- System.Diagnostics.DiagnosticSource (>= 10.0.11)
- System.Text.Json (>= 10.0.11)
- Wolfgang.Etl.Abstractions (>= 0.23.2)
-
.NETStandard 2.0
- Microsoft.Bcl.AsyncInterfaces (>= 10.0.11)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.11)
- System.Diagnostics.DiagnosticSource (>= 10.0.11)
- System.Text.Json (>= 10.0.11)
- Wolfgang.Etl.Abstractions (>= 0.23.2)
-
net10.0
- Microsoft.Bcl.AsyncInterfaces (>= 10.0.11)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.11)
- Wolfgang.Etl.Abstractions (>= 0.23.2)
-
net8.0
- Microsoft.Bcl.AsyncInterfaces (>= 10.0.11)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.11)
- System.Diagnostics.DiagnosticSource (>= 10.0.11)
- System.Text.Json (>= 10.0.11)
- Wolfgang.Etl.Abstractions (>= 0.23.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.