Table of Contents

Class JsonValueReader

Namespace
MassiveDotNet.Serialization
Assembly
MassiveDotNet.dll

Reads a scalar from a Utf8JsonReader positioned on its value token, reporting a malformed value as a JsonException.

public static class JsonValueReader
Inheritance
JsonValueReader
Inherited Members

Remarks

The generated model converters are built from these. Utf8JsonReader's own accessors are the wrong shape for that job: GetInt32() throws InvalidOperationException on a token of the wrong kind and FormatException on a number outside the target's range. Neither is a JsonException, so neither is recognised as a malformed body by the transport, and both would surface from an ordinary REST call as an exception type nothing documents.

One implementation rather than the same token check emitted into every generated converter, for the reason decision D15 keeps filter rendering in RequestUriBuilder: it is tested once here instead of once per generated file, and it cannot drift between them.

Every method leaves the reader on the value it read, so the caller's next Read() advances to the following property name.

Exactly one failure message echoes the value that caused it: the range failure raised when a token is a number the target type cannot hold. This paragraph used to say that no method echoes anything, and issue #65 is what reversed it. A streaming StockAggregate.z was refused in production and the log said only that the number did not fit -- which cannot distinguish a non-integral value from an integral one written as 12.0 from one genuinely past the range. Those are three different causes with three different fixes, and the value is the only thing that tells them apart.

The echo is confined to that one helper, and the confinement IS the rule 11 argument: it is reachable only after its caller has checked reader.TokenType == JsonTokenType.Number, which every caller does and no other path reaches it, so the bytes it quotes are provably a JSON number -- and an API key is not a JSON number. The safety is structural rather than a matter of care taken at each site. The wrong-token-type failure names a token type and has no value in hand; the decimal round-trip failure reads a String, where that proof does not hold and the class of value it could quote back is unbounded. Neither echoes, and neither is to be changed to (D-W21).

Methods

ReadBoolean(ref Utf8JsonReader, string, string)

Reads a boolean.

public static bool ReadBoolean(ref Utf8JsonReader reader, string model, string property)

Parameters

reader Utf8JsonReader

A reader positioned on the value token.

model string

The model being read, named in the failure message.

property string

The property being read, named in the failure message.

Returns

bool

The boolean.

Exceptions

JsonException

The token is not true or false.

ReadDecimal(ref Utf8JsonReader, string, string)

Reads a decimal the wire sent as a string, refusing any value that does not round-trip.

public static decimal ReadDecimal(ref Utf8JsonReader reader, string model, string property)

Parameters

reader Utf8JsonReader

A reader positioned on the value token.

model string

The model being read, named in the failure message.

property string

The property being read, named in the failure message.

Returns

decimal

The decimal, with the scale the wire wrote.

Remarks

The fractional-share family -- dv, dav, ds, decimal_size, decimal_volume -- is declared type: string at all 31 of its sites, so this reads a String. A JSON number is refused, exactly as it was when the family bound to string.

The parse is verified by formatting the result back and comparing bytes, rather than predicted by counting digits. decimal rounds silently and returns true when a value's scaled integer overflows its 96-bit mantissa -- 8827.8140001491929689677164477 does at 29 digits while 12345678901234567890123456789 does not -- so digit count does not predict it, and a threshold set at 29 leaked silent roundings across a randomized corpus. Round-tripping is exact in both directions because the value carries its own scale, which is the same property that lets 4989.0 keep its trailing zero (D38).

The guard also enforces canonical spelling, since a leading +, a redundant zero, a thousands separator, surrounding whitespace, or exponent notation all format back differently. That is stricter than "never rounds" and is accepted deliberately: Massive's wire is canonical, and a refusal is visible where a silent normalisation is not.

Exceptions

JsonException

The token is not a string, or the string is not a decimal this type can carry exactly.

ReadDouble(ref Utf8JsonReader, string, string)

Reads a double.

public static double ReadDouble(ref Utf8JsonReader reader, string model, string property)

Parameters

reader Utf8JsonReader

A reader positioned on the value token.

model string

The model being read, named in the failure message.

property string

The property being read, named in the failure message.

Returns

double

The double.

Exceptions

JsonException

The token is not a number, or does not fit a double.

ReadInt32(ref Utf8JsonReader, string, string)

Reads a 32-bit integer.

public static int ReadInt32(ref Utf8JsonReader reader, string model, string property)

Parameters

reader Utf8JsonReader

A reader positioned on the value token.

model string

The model being read, named in the failure message.

property string

The property being read, named in the failure message.

Returns

int

The integer.

Exceptions

JsonException

The token is not a number, or does not fit an int.

ReadInt64(ref Utf8JsonReader, string, string)

Reads a 64-bit integer.

public static long ReadInt64(ref Utf8JsonReader reader, string model, string property)

Parameters

reader Utf8JsonReader

A reader positioned on the value token.

model string

The model being read, named in the failure message.

property string

The property being read, named in the failure message.

Returns

long

The integer.

Remarks

The range check matters more here than anywhere else in this file: nanosecond timestamps are stored raw as long (decision D5), and a value one past the range silently becoming a double would hand a caller a wrong instant with nothing to notice it.

Exceptions

JsonException

The token is not a number, or does not fit a long.

ReadNullableBoolean(ref Utf8JsonReader, string, string)

Reads a boolean, or null from a JSON null.

public static bool? ReadNullableBoolean(ref Utf8JsonReader reader, string model, string property)

Parameters

reader Utf8JsonReader

A reader positioned on the value token.

model string

The model being read, named in the failure message.

property string

The property being read, named in the failure message.

Returns

bool?

The boolean, or null.

Exceptions

JsonException

The token is neither a boolean nor null.

ReadNullableDecimal(ref Utf8JsonReader, string, string)

Reads a decimal string, or null from a JSON null.

public static decimal? ReadNullableDecimal(ref Utf8JsonReader reader, string model, string property)

Parameters

reader Utf8JsonReader

A reader positioned on the value token.

model string

The model being read, named in the failure message.

property string

The property being read, named in the failure message.

Returns

decimal?

The decimal, or null.

Exceptions

JsonException

The token is neither an exact decimal string nor null.

ReadNullableDouble(ref Utf8JsonReader, string, string)

Reads a double, or null from a JSON null.

public static double? ReadNullableDouble(ref Utf8JsonReader reader, string model, string property)

Parameters

reader Utf8JsonReader

A reader positioned on the value token.

model string

The model being read, named in the failure message.

property string

The property being read, named in the failure message.

Returns

double?

The double, or null.

Exceptions

JsonException

The token is neither a fitting number nor null.

ReadNullableInt32(ref Utf8JsonReader, string, string)

Reads a 32-bit integer, or null from a JSON null.

public static int? ReadNullableInt32(ref Utf8JsonReader reader, string model, string property)

Parameters

reader Utf8JsonReader

A reader positioned on the value token.

model string

The model being read, named in the failure message.

property string

The property being read, named in the failure message.

Returns

int?

The integer, or null.

Exceptions

JsonException

The token is neither a fitting number nor null.

ReadNullableInt64(ref Utf8JsonReader, string, string)

Reads a 64-bit integer, or null from a JSON null.

public static long? ReadNullableInt64(ref Utf8JsonReader reader, string model, string property)

Parameters

reader Utf8JsonReader

A reader positioned on the value token.

model string

The model being read, named in the failure message.

property string

The property being read, named in the failure message.

Returns

long?

The integer, or null.

Exceptions

JsonException

The token is neither a fitting number nor null.

ReadString(ref Utf8JsonReader, string, string)

Reads a string, or null from a JSON null.

public static string? ReadString(ref Utf8JsonReader reader, string model, string property)

Parameters

reader Utf8JsonReader

A reader positioned on the value token.

model string

The model being read, named in the failure message.

property string

The property being read, named in the failure message.

Returns

string

The string, or null.

Exceptions

JsonException

The token is neither a string nor null.