Skip to main content
Version: 0.3.x (0.3.0)

Class ValueObjectConverter

Namespace: AdCodicem.ValueObjects.NewtonsoftJson
Assembly: AdCodicem.ValueObjects.NewtonsoftJson.dll

Reads and writes any value object as its bare underlying value.

public sealed class ValueObjectConverter : JsonConverter

Inheritance​

object ← JsonConverter ← ValueObjectConverter

Inherited Members​

JsonConverter.WriteJson(JsonWriter, object?, JsonSerializer), JsonConverter.ReadJson(JsonReader, Type, object?, JsonSerializer), JsonConverter.CanConvert(Type), JsonConverter.CanRead, JsonConverter.CanWrite, object.Equals(object?), object.Equals(object?, object?), object.GetHashCode(), object.GetType(), object.ReferenceEquals(object?, object?), object.ToString()

Remarks​

One converter covers every value object, because the work is delegated to the runtime descriptor rather than to a type-specific implementation. Newtonsoft.Json resolves converters by reflection anyway, so there is nothing to gain from a generic converter per type here.

It follows the System.Text.Json converter the generator emits: the same rules, and the same values on the wire. The text is the same too, but for a whole , or , which Newtonsoft.Json always writes with a fraction: 1250.0 where System.Text.Json writes 1250. Each serializer reads the other's text as the same value.

adds it to the serializer settings with the two settings it reads value objects best under. puts it on the contract of each value object instead, for code that hands Newtonsoft.Json a contract resolver alone.

A value it refuses is a , the exception Newtonsoft.Json's own converters throw, carrying the code of the rule in under , where reads it: the rule's own code, for a token that is not of the underlying type at all, and for a null read into a value object that cannot be null. A value object written by hand over a type the generator does not support has its value read by Newtonsoft.Json, whose own exception carries no code. A handler of the serializer's event that handles it, as MVC's does, leaves that read without a value: the converter then refuses the token with , rather than as missing.

Methods​

CanConvert(Type)​

Determines whether this instance can convert the specified object type.

public override bool CanConvert(Type objectType)

Parameters​

objectType Type

Type of the object.

Returns​

bool

true if this instance can convert the specified object type; otherwise, false.

ReadJson(JsonReader, Type, object?, JsonSerializer)​

Reads the JSON representation of the object.

public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)

Parameters​

reader JsonReader

The to read from.

objectType Type

Type of the object.

existingValue object?

The existing value of object being read.

serializer JsonSerializer

The calling serializer.

Returns​

object?

The object value.

Remarks​

The value is read as the System.Text.Json converter the generator emits reads it: from the kind of token it writes, and through the value object's rules, so a rejection says which rule refused it.

A value written as a number is read from a string as well, as System.Text.Json reads one under JsonNumberHandling.AllowReadingFromString: the whole text, with no white space, no group separator and no culture. That is how Newtonsoft.Json writes a numeric value object without this converter, through its type converter, so data stored that way still reads once the converter is added.

Newtonsoft.Json reads the token under the serializer's settings before the converter sees it. Under its default , a string that looks like a date becomes a , converted to local time when the text carries an offset; where that date no longer says what the text said, the value is refused rather than rebuilt into something else. A value object therefore refuses any text with an explicit offset, its own output included, since it is written with its offset, +00:00 for UTC. keeps the text, and reads it back.

Under , every number with a fraction or an exponent becomes a , which keeps every digit of a value object. A or value object beyond the range of a then makes the reader throw, and one smaller than its 28 decimal places loses the digits past them, all of them below about 10^-28, where it reads as zero.

WriteJson(JsonWriter, object?, JsonSerializer)​

Writes the JSON representation of the object.

public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)

Parameters​

writer JsonWriter

The to write to.

value object?

The value.

serializer JsonSerializer

The calling serializer.

Remarks​

The value is written as the System.Text.Json converter the generator emits writes it: a number or a boolean as such, and anything else as a string, and included, in the same round-trip form. The serializer's date settings do not apply, so that both serializers write the same text. A whole , or is the one difference: Newtonsoft.Json writes it with a fraction, as the same value. An instance equal to the default whose value the value object rejects is refused with a naming the rule, as the System.Text.Json converter refuses it, rather than written for a reader to refuse.