⚠️ Experimental / pre-1.0. This library is published under a0.x(prerelease) version while the public API settles. Expect breaking changes between releases — including patch bumps — until a stable1.0.0is tagged. See Versioning and the Changelog.
Read and write JSON-stat v2.0 statistical data in .NET. This library
fills the C# gap in the JSON-stat ecosystem and mirrors the
read/navigation interface of the JavaScript Toolkit,
while deliberately omitting its deprecated APIs (Slice() and toTable()) in favour of their
modern replacements (Dice() and Transform()).
- Status: experimental (
0.1.1) — implemented; 25-test xUnit suite targeting .NET 8 (LTS). - Target:
netstandard2.0(runs on .NET Framework 4.6.1+, .NET Core 2.0+, .NET 8+); depends onSystem.Text.Json8.x. Built and tested on .NET 8 (LTS). - Namespace:
JSONstat(brand parity with the JSJSONstat()global; type names stay PascalCase). - License: Apache-2.0 · Author: Xavier Badosa.
Naming note: .NET style guidelines prefer PascalCase namespaces, so an IDE analyzer may flag
JSONstatas a suggestion (not a build error). Because the entry class shares the namespace name, consume it asJSONstat.JSONstat.Parse(...)orusing static JSONstat.JSONstat;thenParse(...). The tests live in a sibling namespace (JSONstatTests) precisely to avoid namespace/type shadowing.
dotnet add package JSONstat
using JSONstat.Models;
using static JSONstat.JSONstat;
var ds = Parse(jsonString).Dataset()!;
ds.Id; // ["concept","area","year"]
ds.N; // total cells
ds.Dimension("area"); // by id
ds.Dimension(2); // by index
ds.Dimension(DimensionRole.Time); // by role
ds.Data(0).Value; // by linear index
ds.Data(new[] { 0, 1, 1 }).Value; // by dimension indices
ds.Data(new Dictionary<string,string> // by dimension/category ids
{ { "area", "ES" }, { "year", "2014" } }).Value;
ds.ValueAt(3); // value only (≈ JS Data(id, false))
ds.Dimension("area").Category("ES").Label; // "Spain"All three response classes are supported: dataset, collection (response.Items, Item(i),
ItemsOf(ResponseClass.Dataset)), and dimension (response.Dimension).
// Subset by filtering dimension categories (replaces deprecated Slice)
var subset = ds.Dice(DiceFilter.FromObject(
new Dictionary<string, IReadOnlyCollection<string>> { { "area", new[] { "GR", "PT" } } }));
// Flat list with full per-cell context
var rows = ds.Unflatten<Datum>(ctx => ctx.Datapoint); // ctx.Coordinates, ctx.N, ctx.Row
// Tabular forms (replaces deprecated toTable)
var table = ds.Transform(new TransformOptions { Type = TransformType.ArrayOfObjects, Status = true });
Console.WriteLine(table.ToJsonString());using JSONstat.Builders;
using static JSONstat.JSONstat;
var response = new DatasetBuilder()
.Label("Demo")
.Dimension("area", d => d.Category(c => c.Ids("GR", "ES", "PT")))
.Dimension("year", d => d.Category(c => c.Ids("2013", "2014")))
.Values(1, 2, 3, 4, 5, 6)
.Status("e")
.Role(r => r.Metric = new[] { "area" })
.BuildResponse();
Console.WriteLine(Serialize(response)); // dense value, string status, round-trips through ParseSparse values (SparseValues) and all three status forms (Status(string) / StatusArray(...)
/ StatusObject(...)) are supported; round-trip fidelity is covered by the test suite.
using JSONstat.Models;
// Toolkit parity: the JS toolkit's JSONstat(url) maps to LoadAsync(url).
var ds = (await JSONstat.LoadAsync(new Uri("https://example.com/data.json"))).Dataset()!;LoadAsync(Uri, HttpClient?, CancellationToken) reuses a shared internal HttpClient
(pass your own to customize base address, headers, timeout, or handler — e.g. for tests).
Synchronous Load(Uri) is also available. Consumers that only Parse pay no HTTP cost.
| In scope | Deferred |
|---|---|
| Dataset read + write | JSON-Schema / semantic validation |
| Full Toolkit navigation | CSV/Arrow/Parquet interop (jsonstat-io) |
Dice, Unflatten, Transform |
Deprecated Toolkit APIs (Slice, toTable) |
HTTP fetching (Load / LoadAsync) |
csharp/
├── README.md # this file (also the NuGet readme)
├── CHANGELOG.md # versioned release history
├── API.md # full API reference (types, methods, properties, enums)
├── JSONstat.sln
├── src/JSONstat/ # netstandard2.0 library
├── tests/JSONstat.Tests/# xUnit (21 tests, 5 fixtures)
└── samples/JSONstat.Samples/
dotnet test JSONstat.sln
dotnet run --project samples/JSONstat.Samples
This project follows Semantic Versioning. While the major
version is 0 (currently 0.1.1), the package is considered
experimental: any release may contain breaking changes, including in patch
releases. A stable, semver-guaranteed 1.0.0 will be tagged once the API is deemed
production-ready.
Releases are tracked in CHANGELOG.md and marked with git tags of
the form v0.1.1.
API.md— complete API reference: every public type, method, property, and enum.