Complete reference for the public API surface of JSON-stat for C# (JSONstat),
targeting netstandard2.0. The library is organised into four namespaces:
| Namespace | Purpose |
|---|---|
JSONstat |
The static entry point: parse and serialize. |
JSONstat.Models |
The in-memory model: response, dataset, dimensions, data. |
JSONstat.Builders |
Fluent authoring of datasets (DatasetBuilder, …). |
JSONstat.Transform |
Dice, Unflatten, Transform and their option/result types. |
JSONstat.IO |
Value/status collections, JSON options. |
Conventions. Types are
sealedwhere possible; properties that mirror the JSON-stat wire format are read/write andpublic, while navigation helpers are marked[JsonIgnore]. Missing observations are represented asnull(a hole in the cube). Navigation methods returnnullfor unknown ids/indices instead of throwing.
- Entry point —
JSONstat - Models (
JSONstat.Models) - Builders (
JSONstat.Builders) - Transform (
JSONstat.Transform) - IO (
JSONstat.IO)
The static class JSONstat is the read/write gateway,
mirroring the JavaScript Toolkit's JSONstat global.
using static JSONstat.JSONstat;
Response response = Parse(jsonString);
Dataset ds = response.Dataset()!;
string back = Serialize(ds);| Member | Signature | Description |
|---|---|---|
FormatVersion |
const string |
The JSON-stat format version this library targets ("2.0"). |
Parse(string) |
Response Parse(string json) |
Parses a JSON-stat response from a UTF-8 string. Throws JsonException on a null result. |
Parse(Stream) |
Response Parse(Stream utf8Json) |
Parses from a stream (synchronous wrapper over ParseAsync). |
ParseAsync |
Task<Response> ParseAsync(Stream, CancellationToken = default) |
Parses from a stream asynchronously. |
Parse(JsonElement) |
Response Parse(JsonElement element) |
Parses an already-read JsonElement. |
Serialize(Response) |
string Serialize(Response) |
Serializes a response to a JSON string. |
Serialize(Dataset) |
string Serialize(Dataset) |
Serializes a standalone dataset to a JSON string. |
Serialize(Stream, Response) |
void Serialize(Stream, Response) |
Serializes a response to a stream (synchronous). |
SerializeAsync |
Task SerializeAsync(Stream, Response, CancellationToken = default) |
Serializes a response to a stream asynchronously. |
Load(Uri) |
Response Load(Uri url) |
Fetches (HTTP GET) and parses a JSON-stat response using the shared internal client. |
Load(Uri, HttpClient?) |
Response Load(Uri url, HttpClient? client) |
Fetches and parses using the supplied client (synchronous wrapper over LoadAsync). |
LoadAsync(Uri) |
Task<Response> LoadAsync(Uri url, CancellationToken = default) |
Fetches and parses asynchronously using the shared client. Equivalent to the JS toolkit's JSONstat(url). |
LoadAsync(Uri, HttpClient?, CancellationToken) |
Task<Response> LoadAsync(Uri url, HttpClient? client, CancellationToken = default) |
Fetches and parses asynchronously with a custom HttpClient. Throws ArgumentNullException for a null url, HttpRequestException on failure/non-success. |
Parse dispatches by the class property to a Dataset,
Collection, or Dimension; see
ResponseConverter. All (de)serialization
shares the cached JsonOptions.Default.
Response is the parsed top-level JSON-stat
object. It dispatches to the class-specific object and exposes the Toolkit-parity
navigation entry points.
| Member | Type | Description |
|---|---|---|
Class |
ResponseClass |
The response class. |
Version |
string? |
JSON-stat version. |
Label |
string? |
Short descriptive text. |
Datasets |
IReadOnlyList<Dataset> |
All datasets reachable from the response (one for dataset responses, embedded ones for collections). |
Collection |
Collection? |
The parsed collection, or null. |
Dimension |
Dimension? |
The parsed dimension, or null. |
Items |
IReadOnlyList<LinkItem> |
The collection items (collection responses). |
| Method | Signature | Description |
|---|---|---|
Dataset() |
Dataset? Dataset() |
The first dataset, or null. |
Dataset(int) |
Dataset? Dataset(int index) |
The dataset at index, or null when out of range. |
Dataset(string) |
Dataset? Dataset(string id) |
The dataset whose label matches id (ordinal match), or null. |
Item(int) |
LinkItem? Item(int index) |
The collection item at index, or null. |
ItemsOf |
IReadOnlyList<LinkItem> ItemsOf(ResponseClass filter) |
The collection items of a given class. |
Dataset is the core type: a multi-dimensional
cube of values with dimensions, roles, status and metadata. It carries the
read/navigation surface and (in Dataset.Transform.cs)
the Dice / Unflatten / Transform transforms.
| Member | Type | Wire name | Description |
|---|---|---|---|
Version |
string? |
version |
JSON-stat version (defaults "2.0"). |
Class |
ResponseClass |
class |
Always Dataset. |
Label |
string? |
label |
Short descriptive text. |
Source |
string? |
source |
Source description. |
Updated |
string? |
updated |
Update time (ISO 8601). |
Id |
string[]? |
id |
Ordered dimension ids. |
Size |
int[]? |
size |
Category counts per dimension (same order as Id). |
Role |
Role? |
role |
Optional dimension roles. |
DimensionMap |
Dictionary<string, Dimension> |
dimension |
The dimension map. |
Value |
ValueCollection? |
value |
Dense array or sparse object. |
Status |
StatusCollection? |
status |
Array, string, or object. |
Note |
string[]? |
note |
Annotations. |
Link |
Link? |
link |
Related resources. |
Extension |
JsonElement? |
extension |
Provider-specific extension. |
ExtensionData |
IDictionary<string, JsonElement>? |
(extension) | Unmodelled extension properties ([JsonExtensionData]). |
| Member | Signature | Description |
|---|---|---|
N |
long N (get) |
Total cells in the cube, including missing (product of Size). |
Dimensions |
IReadOnlyList<Dimension> (get) |
The dimensions in id order. |
Dimension(int) |
Dimension? Dimension(int index) |
Dimension at index, or null. |
Dimension(string) |
Dimension? Dimension(string id) |
Dimension by id, or null. |
Dimension(DimensionRole) |
Dimension? Dimension(DimensionRole role) |
First dimension with the given role, or null. |
LinearOf |
long LinearOf(int[] indices) |
Encodes per-dimension category indices into a linear index (row-major). |
IndicesOf |
int[]? IndicesOf(IReadOnlyDictionary<string, string> byId) |
Resolves dimension-id/category-id pairs into category indices; null when unresolved. |
| Member | Signature | Description |
|---|---|---|
ValueAt(int) |
double? ValueAt(int linear) |
Value at a linear index (null when missing). Equivalent to the Toolkit's Data(id, false). |
ValueAt(int[]) |
double? ValueAt(int[] indices) |
Value at the given category indices. |
ValueAt(byId) |
double? ValueAt(IReadOnlyDictionary<string, string> byId) |
Value resolved by dimension-id/category-id pairs. |
StatusAt |
string? StatusAt(int linear) |
Status at a linear index, or null. |
| Member | Signature | Description |
|---|---|---|
Data() |
IReadOnlyList<Datum> Data() |
All observations in linear order (cached). |
Data(int) |
Datum Data(int linear) |
The observation at a linear index. |
Data(int[]) |
Datum? Data(int[] indices) |
Observation at the given category indices; null if invalid. |
Data(byId) |
Datum? Data(IReadOnlyDictionary<string, string> byId) |
Observation resolved by dimension-id/category-id pairs; null if invalid. |
EnumerateData |
IEnumerable<Datum> EnumerateData() |
Lazily enumerates observations without materializing the whole cube. |
See Transform.
| Member | Signature | Description |
|---|---|---|
Dice |
Dataset Dice(DiceFilter? filter = null, DiceOptions? options = null) |
Returns a filtered subset (never mutates the receiver). |
Unflatten<T> |
IReadOnlyList<T> Unflatten<T>(Func<UnflattenContext<T>, T> selector) |
Converts the cube to a flat list, invoking selector once per cell. |
Transform |
TransformResult Transform(TransformOptions? options = null) |
Converts the cube to a tabular form. |
Lifecycle. On parse,
IJsonOnDeserialized.OnDeserializedcalls the internalWire()to link dimension ids/roles/sizes and computeN. Builders callWire()themselves; you normally never invoke it.
Dimension is a dataset dimension carrying its
Category and metadata, plus the Category navigation family.
| Member | Type | Wire name | Description |
|---|---|---|---|
Version |
string? |
version |
Present on dimension responses. |
Class |
ResponseClass? |
class |
Present on dimension responses; omitted for dataset dimensions. |
Label |
string? |
label |
Short descriptive text. |
CategoryInfo |
Category |
category |
The category information. |
Href |
string? |
href |
URL to an external dimension definition. |
Extension |
JsonElement? |
extension |
Provider-specific extension. |
Link |
Link? |
link |
Related resources. |
Note |
string[]? |
note |
Annotations. |
ExtensionData |
IDictionary<string, JsonElement>? |
(extension) | Unmodelled extension properties. |
| Member | Signature | Description |
|---|---|---|
Id |
string (get) |
The dimension id (from the surrounding dimension map key). |
Role |
DimensionRole (get) |
The resolved role (never written to the wire). |
CategoryLabels |
IReadOnlyList<string> (get) |
The category labels in order. |
Categories |
IReadOnlyList<CategoryEntry> (get) |
The categories as entries. |
Category(int) |
CategoryEntry? Category(int index) |
Category at index, or null. |
Category(string) |
CategoryEntry? Category(string id) |
Category by id, or null. |
ds.Dimension("area")!.Category("ES")!.Label; // "Spain"Category is the category object of a
dimension: ordered ids plus per-category labels, hierarchies, coordinates and units.
| Member | Type | Wire name | Description |
|---|---|---|---|
Index |
Dictionary<string, int>? |
index |
Category ordering. Accepts the array form (["M","F"]) or object form ({"M":0,"F":1}) on read; always writes the object form. null for constant dimensions. |
Label |
Dictionary<string, string>? |
label |
Per-category labels (falls back to the id). |
Child |
Dictionary<string, string[]>? |
child |
Hierarchical relationships (parent id → child ids). |
Coordinates |
Dictionary<string, double[]>? |
coordinates |
Geographic coordinates [longitude, latitude]. |
Unit |
Dictionary<string, Unit>? |
unit |
Units of measure for metric-role categories. |
ExtensionData |
IDictionary<string, JsonElement>? |
(extension) | Provider-specific extension properties. |
| Member | Signature | Description |
|---|---|---|
Ids |
IReadOnlyList<string> (get) |
The category ids in order. |
Labels |
IReadOnlyList<string> (get) |
The category labels in order. |
Entries |
IReadOnlyList<CategoryEntry> (get) |
The categories as entries. |
Entry(int) |
CategoryEntry? Entry(int index) |
Category at index, or null. |
Entry(string) |
CategoryEntry? Entry(string id) |
Category by id, or null. |
PositionOf |
int? PositionOf(string id) |
Position of a category id, or null when unknown. |
Read/write of both array and object index forms is handled by the internal
CategoryIndexConverter.
CategoryEntry is an immutable, flattened
view of a single category, returned by the Category/Entry navigation family.
| Member | Type | Description |
|---|---|---|
Id |
string (get) |
The category id. |
Label |
string (get) |
The category label (falls back to the id). |
Index |
int (get) |
The category position within its dimension. |
Coordinates |
double[]? (get) |
Geographic coordinates [longitude, latitude], if any. |
Unit |
Unit? (get) |
Unit of measure, for metric-role categories. |
The constructor is
CategoryEntry(string id, string label, int index, double[]? coordinates, Unit? unit).
Datum is one observation: a value and, optionally,
its status. Returned by the Data navigation family; Value is null for missing
observations.
| Member | Type | Description |
|---|---|---|
Value |
double? (get) |
The observation value, or null when missing. |
Status |
string? (get) |
The observation status, or null when none. |
IsMissing |
bool (get) |
true when the observation is missing. |
Deconstruct |
void Deconstruct(out double? value, out string? status) |
Deconstructs the observation (enables tuple patterns). |
The constructor is Datum(double? value, string? status).
foreach (var (value, status) in ds.Data()) { /* ... */ }Collection is a collection response: a set of
referenced or embedded items.
| Member | Type | Wire name | Description |
|---|---|---|---|
Version |
string? |
version |
JSON-stat version. |
Class |
ResponseClass |
class |
Always Collection. |
Href |
string? |
href |
URL of the collection. |
Label |
string? |
label |
Short descriptive text. |
Updated |
string? |
updated |
Update time (ISO 8601). |
Link |
Link? |
link |
Link relations; link.item lists the items. |
Extension |
JsonElement? |
extension |
Provider-specific extension. |
ExtensionData |
IDictionary<string, JsonElement>? |
(extension) | Unmodelled extension properties. |
| Member | Signature | Description |
|---|---|---|
Items |
IReadOnlyList<LinkItem> (get) |
The collection items. |
Item(int) |
LinkItem? Item(int index) |
The item at index, or null. |
ItemsOf |
IReadOnlyList<LinkItem> ItemsOf(ResponseClass filter) |
The items of a given class. |
Role assigns special roles to dimensions.
| Member | Type | Description |
|---|---|---|
Time |
string[]? |
Dimension ids with the time role. |
Geo |
string[]? |
Dimension ids with the geo role. |
Metric |
string[]? |
Dimension ids with the metric role. |
IsEmpty |
bool (get) |
true when no role is assigned. |
The internal RoleOf(string) resolves a
dimension id to a DimensionRole.
LinkItem is a single entry in a link array
(e.g. an entry of a collection's link.item). Link
maps relation names to arrays of LinkItem.
| Member | Type | Description |
|---|---|---|
Href |
string? |
URL of the related resource. |
Rel |
string? |
IANA link relation (e.g. "item", "self"). |
Type |
string? |
Media type of the related resource. |
Label |
string? |
Short descriptive text. |
Version |
string? |
JSON-stat version, when embedded. |
Class |
ResponseClass? |
Class of the linked/embedded resource, when known. |
Extension |
JsonElement? |
Embedded content of the linked resource, if present. |
| Member | Type | Description |
|---|---|---|
Item |
LinkItem[]? |
Items referenced by the "item" relation (collections). |
Unit is unit-of-measure metadata for metric-role
categories. Decimals is required when a unit is present.
| Member | Type | Description |
|---|---|---|
Decimals |
int? |
Number of decimals (required when unit is present). |
Label |
string? |
Unit text displayed after the values. |
Symbol |
string? |
Unit symbol (e.g. "$", "%"). |
Position |
string? |
Symbol position: "start" or "end" (default "end"). |
ResponseClass is carried by the class
property. Serialized as a lower-case string by the JSON options.
| Value | Meaning |
|---|---|
Dataset |
A single dataset (cube) with its data and metadata. |
Dimension |
A standalone dimension node. |
Collection |
A collection of referenced/embedded items. |
Bundle |
Pre-2.0 bundle (deprecated; kept for parsing tolerance). |
DimensionRole is the resolved role of a
dimension. The on-the-wire role object only knows time, geo, metric;
Classification is a JavaScript-Toolkit convention for unroled dimensions and is
never written to the wire.
| Value | Meaning |
|---|---|
Time |
Temporal dimension (role.time). |
Geo |
Geographic dimension (role.geo). |
Metric |
Metric/measure dimension (role.metric). |
Classification |
No role assigned (Toolkit convention only). |
Fluent authoring of datasets. Build a Dataset or Response,
then Serialize it. The builders wire sizes and call
Wire() for you.
using JSONstat.Builders;
using static JSONstat.JSONstat;
var response = new DatasetBuilder()
.Label("Demo")
.Dimension("area", d => d.Category(c => c.Ids("GR", "ES", "PT")))
.Values(1, 2, 3)
.Status("e")
.BuildResponse();
Console.WriteLine(Serialize(response));DatasetBuilder assembles a dataset.
| Member | Signature | Description |
|---|---|---|
Label |
DatasetBuilder Label(string label) |
Sets the dataset label. |
Source |
DatasetBuilder Source(string source) |
Sets the source. |
Updated |
DatasetBuilder Updated(string updated) |
Sets the update time. |
Dimension |
DatasetBuilder Dimension(string id, Action<DimensionBuilder> configure) |
Adds a dimension by id and configures it. |
Role |
DatasetBuilder Role(Action<Role> configure) |
Configures the dimension roles. |
Values |
DatasetBuilder Values(params double?[] values) |
Sets the dense values (clears sparse). |
SparseValues |
DatasetBuilder SparseValues(IDictionary<string, double?> values) |
Sets the sparse values (object form; clears dense). |
Status |
DatasetBuilder Status(string uniform) |
Sets a uniform string status. |
StatusArray |
DatasetBuilder StatusArray(params string?[] values) |
Sets an array status. |
StatusObject |
DatasetBuilder StatusObject(IDictionary<string, string> values) |
Sets an object status. |
Build |
Dataset Build() |
Builds the dataset (linked and ready to serialize). |
BuildResponse |
Response BuildResponse() |
Builds a Response wrapping the dataset. |
DimensionBuilder configures a dimension.
| Member | Signature | Description |
|---|---|---|
Label |
DimensionBuilder Label(string label) |
Sets the dimension label. |
Category |
DimensionBuilder Category(Action<CategoryBuilder> configure) |
Configures the dimension's categories. |
CategoryBuilder configures a dimension's
categories.
| Member | Signature | Description |
|---|---|---|
Ids |
CategoryBuilder Ids(params string[] ids) |
Adds category ids in order (auto-labels with the id). |
Label |
CategoryBuilder Label(string id, string label) |
Sets the label of a category id (adds it to the order if new). |
Child |
CategoryBuilder Child(string parent, params string[] children) |
Adds a parent → children hierarchy entry. |
Coordinates |
CategoryBuilder Coordinates(string id, double longitude, double latitude) |
Sets geographic coordinates for a category id. |
Unit |
CategoryBuilder Unit(string id, Unit unit) |
Configures the unit for a metric category id. |
The non-deprecated Toolkit replacements. (Slice() and toTable() are intentionally
absent.)
Dataset.Dice creates a subset by
filtering dimension categories. It recomputes value/status in row-major order and
preserves labels, hierarchies, coordinates and units for the kept categories.
var subset = ds.Dice(DiceFilter.FromObject(
new Dictionary<string, IReadOnlyCollection<string>> { { "area", new[] { "GR", "PT" } } }),
new DiceOptions { Drop = false });| Member | Signature | Description |
|---|---|---|
Empty |
DiceFilter Empty() |
An empty filter (keeps all categories). |
FromObject |
DiceFilter FromObject(IDictionary<string, IReadOnlyCollection<string>> filter) |
Builds a filter from the object form: dimension id → kept category ids. |
FromArray(params) |
DiceFilter FromArray(params (string dimensionId, string categoryId)[] pairs) |
Builds a filter from dimension/category pairs. |
FromArray(IEnumerable) |
DiceFilter FromArray(IEnumerable<(string dimensionId, string categoryId)> pairs) |
Builds a filter from an enumerable of pairs. |
| Member | Type | Description |
|---|---|---|
Clone |
bool |
Always effectively true; Dice never mutates its receiver. |
Drop |
bool |
Treat the filter as an anti-filter (exclude the listed categories). |
OValue |
bool |
Force value to object (sparse) form in the result. |
OStatus |
bool |
Force status to object form in the result. |
Dataset.Unflatten<T> converts the
cube to a flat list, invoking selector once per cell with a context that carries
coordinates, the datapoint, the cell counter, and the accumulator built so far.
var rows = ds.Unflatten(ctx => ctx.Datapoint); // flat list of Datum
var typed = ds.Unflatten(ctx => new MyRow(ctx.Coordinates, ctx.Datapoint.Value));| Member | Type | Description |
|---|---|---|
Coordinates |
IReadOnlyDictionary<string, string> (get) |
Dimension id → category id for the current cell. |
Datapoint |
Datum (get) |
The value and status of the current cell. |
N |
int (get) |
The linear cell counter. |
Row |
IReadOnlyList<T> (get) |
The rows accumulated so far. |
Dataset.Transform converts the
cube to a tabular form. The four output shapes share a single
TransformResult return type.
var table = ds.Transform(new TransformOptions {
Type = TransformType.ArrayOfObjects,
Status = true
});
Console.WriteLine(table.ToJsonString());| Member | Type | Default | Description |
|---|---|---|---|
Type |
TransformType |
ArrayOfArrays |
The output shape. |
Field |
TransformField? |
type-dependent | Dimension field form (Label for ArrayOfArrays, else Id). |
Content |
TransformContent? |
Label |
Category content form. |
Status |
bool |
false |
Include the status column. |
ValueLabel |
string |
"Value" |
Label for the value column. |
StatusLabel |
string |
"Status" |
Label for the status column. |
Meta |
bool |
false |
Include metadata (reserved; currently ignored). |
By |
string? |
null |
Dimension id to transpose on (reserved; currently ignored). |
Prefix |
string? |
null |
Prefix for transposed properties (reserved; currently ignored). |
Drop |
string[]? |
null |
Dimension ids to exclude from the output. |
Comma |
bool |
false |
Use a comma decimal mark for values (es-ES). |
| Member | Type | Description |
|---|---|---|
Element |
JsonElement (get) |
The tabular output as a JsonElement for typed access. |
ToJsonString |
string ToJsonString() |
The tabular output as a JSON string. |
TransformType — the tabular output shape:
| Value | Shape |
|---|---|
ArrayOfArrays |
A header row followed by data rows. |
ArrayOfObjects |
One object per cell. |
ObjectOfArrays |
An object whose values are column arrays. |
Object |
An object keyed by a ` |
TransformField — the dimension
field (column key) form: Id or Label.
TransformContent — the category
content (cell value) form: Id or Label.
ValueCollection models the dataset value
property, which on the wire is either a dense array (with null holes) or a sparse
object keyed by linear index. Read/write is handled by the internal
ValueCollectionConverter.
| Member | Signature | Description |
|---|---|---|
IsSparse |
bool (get) |
true when stored as a sparse object. |
DenseOf |
ValueCollection DenseOf(double?[] values) |
Builds a dense value collection. |
SparseOf |
ValueCollection SparseOf(Dictionary<string, double?> values) |
Builds a sparse value collection. |
Empty |
ValueCollection Empty() |
Builds an empty dense value collection. |
GetValue |
double? GetValue(int linear) |
The value at the given linear index, or null when missing. |
Enumerate |
IEnumerable<double?> Enumerate(int count) |
Enumerates count values in linear order. |
ToDense |
ValueCollection ToDense(int count) |
Converts to dense form (used by Dice). |
StatusCollection normalizes the status
property into one of the three legal wire forms (array / string / object) plus an
absent form. Read/write is handled by the internal
StatusCollectionConverter.
| Member | Signature | Description |
|---|---|---|
Kind |
StatusKind (get) |
The current wire form. |
None |
StatusCollection None() |
An empty (absent) status. |
ArrayOf |
StatusCollection ArrayOf(string?[] values) |
Builds an array-form status. |
StringOf |
StatusCollection StringOf(string value) |
Builds a uniform string-form status. |
ObjectOf |
StatusCollection ObjectOf(Dictionary<string, string> values) |
Builds an object-form status. |
GetStatus |
string? GetStatus(int linear) |
Resolves the status for a linear index (precedence object → array → string). |
StatusKind — the wire form of status.
| Value | Meaning |
|---|---|
None |
No status property present. |
Array |
An array with one status per value. |
String |
A single status string applied to all values. |
Object |
An object mapping linear indices to status codes. |
JsonOptions provides the shared serializer
configuration: camelCase naming, WhenWritingNull ignore condition, the
ResponseConverter, and a string enum
converter.
| Member | Signature | Description |
|---|---|---|
Default |
JsonSerializerOptions Default (get) |
The cached, default options instance (safe to reuse). |
Build |
JsonSerializerOptions Build() |
Builds a fresh options instance configured for JSON-stat v2.0. |
README.md— install, quick start, scope.