IJsonMemberConverter<T>

Namespace: SnowBank.Data.Json · interface

Implements: IJsonPacker<T>, IJsonDeserializer<T>

Convenience bundle for a symmetric custom converter attached to a member (or a type) via JsonConvertWithAttribute or [JsonConverter(typeof(...))]

Remarks

Converter recognition is per facet: a named converter is honored for whichever of IJsonPacker (value to JSON) and IJsonDeserializer (JSON to value) it implements. A type that is only ever written (or only ever read) can implement a single facet; any attempt to use the missing direction fails with an exception naming the facet to implement. This interface is the convenience bundle for the common symmetric case, never a requirement.

Implementations never see null or missing values: the serialization pipeline handles them (and the lifting of a converter written for T over a T? member) before invoking the converter, on both sides. A converter may also be declared for the nullable form itself (IJsonMemberConverter<DateTime?> on a DateTime? member): the exact form wins over the lift, and the converter then owns every PRESENT value, so it can answer "no value" for a present-but-unreadable input (an empty string, an unparseable token) - distinctly from default(T), which stays a real value, and from JSON null, which stays the pipeline's. The T? declaration transfers the READ side only: Pack still never sees null, so a member converter cannot represent absence for a nullable member whose absent form is not JSON null, unless that absent form only matters when reading.

A source-generated IJsonConverter also satisfies this contract (it implements both parents), so a generated whole-type converter can be named on a member without any adapter.