Skip to main content

RtAttributesConverter

Namespace: Meshmakers.Octo.Runtime.Contracts.Serialization

System.Text.Json counterpart of RtNewtonsoftAttributesConverter. Materializes the attribute dictionary of RtTypeWithAttributes (the base of RtEntity and RtRecord) on deserialize.

public sealed class RtAttributesConverter : JsonConverter<IReadOnlyDictionary<String, Object>>

Inheritance Object → JsonConverter → JsonConverter<IReadOnlyDictionary<String, Object>> → RtAttributesConverter

Remarks:

Why this exists.RtTypeWithAttributes.Attributes is a get-only IReadOnlyDictionary<TKey, TValue> over a private backing field. STJ serializes the getter fine, but on deserialize it cannot write a get-only property and would silently discard the whole dictionary — the classic Newtonsoft→STJ trap. RtEntity / RtRecord therefore carry [JsonConstructor] on the attribute-taking constructor so STJ routes the dictionary through the constructor, and this converter (registered against the constructor's IReadOnlyDictionary<TKey, TValue> parameter type) does the value materialization.

Value materialization mirrors the production round-trip behaviour of RtNewtonsoftAttributesConverter (in-memory JObject.FromObjectJToken.ToObject, which preserves the source CLR type in JValue.Value): integers that fit in Int32 stay Int32, larger integers become Int64; reals stay Double; ISO-8601 strings become DateTime; JSON objects carrying a CkRecordId become nested RtRecord instances; arrays become List<T> of Object. Producing CLR scalars (rather than leaving raw s) is required by downstream consumers such as GetAttributeValue<T> (which calls Convert.ChangeType(Object, TypeCode)) and by the MongoDB BSON serializer, which dispatches on the value's CLR type.

The boxing rules are enforced as a contract by Sdk.Common.PipelineParityTests.AttributeRoundTripClrTypeParityTests, which uses Newtonsoft as the oracle. Some divergences are irreducible (float vs double, decimal vs double, DateTimeOffset vs DateTime — JSON has no source-CLR-type marker for those); they are listed in AttributeValueParityCorpus.IrreducibleDivergences.

Properties

HandleNull

public bool HandleNull { get; }

Property Value

Boolean

Type

public Type Type { get; }

Property Value

Type

Constructors

RtAttributesConverter()

public RtAttributesConverter()

Methods

Read(out Utf8JsonReader, Type, JsonSerializerOptions)

public IReadOnlyDictionary<string, object> Read(out Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)

Parameters

reader Utf8JsonReader

typeToConvert Type

options JsonSerializerOptions

Returns

IReadOnlyDictionary<String, Object>

Write(Utf8JsonWriter, IReadOnlyDictionary<String, Object>, JsonSerializerOptions)

public void Write(Utf8JsonWriter writer, IReadOnlyDictionary<string, object> value, JsonSerializerOptions options)

Parameters

writer Utf8JsonWriter

value IReadOnlyDictionary<String, Object>

options JsonSerializerOptions