<PackageReference Include="System.Text.Json" Version="9.0.6" />

JsonConverter<T>

public abstract class JsonConverter<T> : JsonConverter
Converts an object or value to or from JSON.
using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text.Json.Serialization.Converters; using System.Text.Json.Serialization.Metadata; namespace System.Text.Json.Serialization { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public abstract class JsonConverter<[System.Runtime.CompilerServices.Nullable(2)] T> : JsonConverter { private JsonConverter<T> _fallbackConverterForPropertyNameSerialization; public virtual bool HandleNull { get { base.UsesDefaultHandleNull = true; return false; } } public sealed override Type Type { get; } = typeof(T); internal bool ReadCore(ref Utf8JsonReader reader, out T value, JsonSerializerOptions options, ref ReadStack state) { try { if (state.IsContinuation || base.IsRootLevelMultiContentStreamingConverter || ref reader.TryAdvanceWithOptionalReadAhead(base.RequiresReadAhead)) { bool isPopulatedValue; bool flag = TryRead(ref reader, state.Current.JsonTypeInfo.Type, options, ref state, out value, out isPopulatedValue); if (flag && !reader.AllowMultipleValues && !reader.Read() && !reader.IsFinalBlock) { state.Current.ReturnValue = value; flag = false; } return flag; } if (state.SupportContinuation) { object returnValue = state.Current.ReturnValue; if (returnValue != null) { value = (T)returnValue; goto IL_004d; } } value = default(T); goto IL_004d; IL_004d: return reader.IsFinalBlock; } catch (Exception ex) { Exception ex2 = ex; JsonReaderException ex3 = ex2 as JsonReaderException; if (ex3 == null) { if (!(ex2 is FormatException)) { if (!(ex2 is InvalidOperationException)) { JsonException ex4 = ex2 as JsonException; if (ex4 == null) { if (ex2 is NotSupportedException && !ex.Message.Contains(" Path: ")) ThrowHelper.ThrowNotSupportedException(ref state, ref reader, ex); } else if (ex4.Path == null) { ThrowHelper.AddJsonExceptionInformation(ref state, ref reader, ex4); } } else if (ex.Source == "System.Text.Json.Rethrowable") { ThrowHelper.ReThrowWithPath(ref state, ref reader, ex); } } else if (ex.Source == "System.Text.Json.Rethrowable") { ThrowHelper.ReThrowWithPath(ref state, ref reader, ex); } } else ThrowHelper.ReThrowWithPath(ref state, ex3); throw; } } internal bool WriteCore(Utf8JsonWriter writer, [In] [System.Runtime.CompilerServices.IsReadOnly] ref T value, JsonSerializerOptions options, ref WriteStack state) { try { return TryWrite(writer, ref value, options, ref state); } catch (Exception ex) { if (!state.SupportAsync) state.DisposePendingDisposablesOnException(); Exception ex2 = ex; if (!(ex2 is InvalidOperationException)) { JsonException ex3 = ex2 as JsonException; if (ex3 != null) { if (ex3.Path == null) ThrowHelper.AddJsonExceptionInformation(ref state, ex3); } else if (ex2 is NotSupportedException && !ex.Message.Contains(" Path: ")) { ThrowHelper.ThrowNotSupportedException(ref state, ex); } } else if (ex.Source == "System.Text.Json.Rethrowable") { ThrowHelper.ReThrowWithPath(ref state, ex); } throw; } } protected internal JsonConverter() { base.IsValueType = typeof(T).IsValueType; if (HandleNull) { base.HandleNullOnRead = true; base.HandleNullOnWrite = true; } else if (base.UsesDefaultHandleNull) { base.HandleNullOnRead = (default(T) != null); base.HandleNullOnWrite = false; } } public override bool CanConvert(Type typeToConvert) { return typeToConvert == typeof(T); } private protected override ConverterStrategy GetDefaultConverterStrategy() { return ConverterStrategy.Value; } internal sealed override JsonTypeInfo CreateJsonTypeInfo(JsonSerializerOptions options) { return new JsonTypeInfo<T>(this, options); } internal sealed override void WriteAsObject(Utf8JsonWriter writer, object value, JsonSerializerOptions options) { T value2 = JsonSerializer.UnboxOnWrite<T>(value); Write(writer, value2, options); } internal sealed override bool OnTryWriteAsObject(Utf8JsonWriter writer, object value, JsonSerializerOptions options, ref WriteStack state) { T value2 = JsonSerializer.UnboxOnWrite<T>(value); return OnTryWrite(writer, value2, options, ref state); } internal sealed override void WriteAsPropertyNameAsObject(Utf8JsonWriter writer, object value, JsonSerializerOptions options) { T value2 = JsonSerializer.UnboxOnWrite<T>(value); WriteAsPropertyName(writer, value2, options); } internal sealed override void WriteAsPropertyNameCoreAsObject(Utf8JsonWriter writer, object value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { T value2 = JsonSerializer.UnboxOnWrite<T>(value); WriteAsPropertyNameCore(writer, value2, options, isWritingExtensionDataProperty); } internal sealed override void WriteNumberWithCustomHandlingAsObject(Utf8JsonWriter writer, object value, JsonNumberHandling handling) { T value2 = JsonSerializer.UnboxOnWrite<T>(value); WriteNumberWithCustomHandling(writer, value2, handling); } internal sealed override bool TryWriteAsObject(Utf8JsonWriter writer, object value, JsonSerializerOptions options, ref WriteStack state) { T value2 = JsonSerializer.UnboxOnWrite<T>(value); return TryWrite(writer, ref value2, options, ref state); } internal virtual bool OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, ref WriteStack state) { Write(writer, value, options); return true; } internal virtual bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, [System.Runtime.CompilerServices.ScopedRef] ref ReadStack state, out T value) { value = Read(ref reader, typeToConvert, options); return true; } [return: System.Runtime.CompilerServices.Nullable(2)] public abstract T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options); internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, [System.Runtime.CompilerServices.ScopedRef] ref ReadStack state, out T value, out bool isPopulatedValue) { if (reader.TokenType == JsonTokenType.Null && !base.HandleNullOnRead && !state.IsContinuation) { if (default(T) != null) ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type); value = default(T); isPopulatedValue = false; return true; } if (base.ConverterStrategy == ConverterStrategy.Value) { if (base.IsInternalConverter) { if (state.Current.NumberHandling.HasValue && base.IsInternalConverterForNumberType) value = ReadNumberWithCustomHandling(ref reader, state.Current.NumberHandling.Value, options); else value = Read(ref reader, typeToConvert, options); } else { JsonTokenType tokenType = reader.TokenType; int currentDepth = reader.CurrentDepth; long bytesConsumed = reader.BytesConsumed; if (state.Current.NumberHandling.HasValue && base.IsInternalConverterForNumberType) value = ReadNumberWithCustomHandling(ref reader, state.Current.NumberHandling.Value, options); else value = Read(ref reader, typeToConvert, options); VerifyRead(tokenType, currentDepth, bytesConsumed, true, ref reader); } isPopulatedValue = false; return true; } bool isContinuation = state.IsContinuation; bool flag; if (base.CanBePolymorphic) { flag = OnTryRead(ref reader, typeToConvert, options, ref state, out value); isPopulatedValue = false; return true; } JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo; object returnValue = state.Current.ReturnValue; state.Push(); if (!isContinuation) state.Current.OriginalDepth = reader.CurrentDepth; if (returnValue != null && jsonPropertyInfo != null && !jsonPropertyInfo.IsForTypeInfo) state.Current.HasParentObject = true; flag = OnTryRead(ref reader, typeToConvert, options, ref state, out value); isPopulatedValue = state.Current.IsPopulating; state.Pop(flag); return flag; } internal sealed override bool OnTryReadAsObject(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, [System.Runtime.CompilerServices.ScopedRef] ref ReadStack state, out object value) { T value2; bool result = OnTryRead(ref reader, typeToConvert, options, ref state, out value2); value = value2; return result; } internal sealed override bool TryReadAsObject(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, [System.Runtime.CompilerServices.ScopedRef] ref ReadStack state, out object value) { T value2; bool isPopulatedValue; bool result = TryRead(ref reader, typeToConvert, options, ref state, out value2, out isPopulatedValue); value = value2; return result; } internal sealed override object ReadAsObject(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return Read(ref reader, typeToConvert, options); } internal sealed override object ReadAsPropertyNameAsObject(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return ReadAsPropertyName(ref reader, typeToConvert, options); } internal sealed override object ReadAsPropertyNameCoreAsObject(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return ReadAsPropertyNameCore(ref reader, typeToConvert, options); } internal sealed override object ReadNumberWithCustomHandlingAsObject(ref Utf8JsonReader reader, JsonNumberHandling handling, JsonSerializerOptions options) { return ReadNumberWithCustomHandling(ref reader, handling, options); } private static bool IsNull(T value) { return value == null; } internal bool TryWrite(Utf8JsonWriter writer, [In] [System.Runtime.CompilerServices.IsReadOnly] ref T value, JsonSerializerOptions options, ref WriteStack state) { if (writer.CurrentDepth >= options.EffectiveMaxDepth) ThrowHelper.ThrowJsonException_SerializerCycleDetected(options.EffectiveMaxDepth); if (default(T) == null && !base.HandleNullOnWrite && IsNull(value)) { writer.WriteNullValue(); return true; } if (base.ConverterStrategy == ConverterStrategy.Value) { int currentDepth = writer.CurrentDepth; if (state.Current.NumberHandling.HasValue && base.IsInternalConverterForNumberType) WriteNumberWithCustomHandling(writer, value, state.Current.NumberHandling.Value); else Write(writer, value, options); VerifyWrite(currentDepth, writer); return true; } bool isContinuation = state.IsContinuation; bool flag; if (!base.IsValueType && value != null && state.Current.PolymorphicSerializationState != PolymorphicSerializationState.PolymorphicReEntryStarted) { JsonTypeInfo jsonTypeInfo = state.PeekNestedJsonTypeInfo(); JsonConverter jsonConverter = (base.CanBePolymorphic || jsonTypeInfo.PolymorphicTypeResolver != null) ? ResolvePolymorphicConverter(value, jsonTypeInfo, options, ref state) : null; if (!isContinuation && options.ReferenceHandlingStrategy != 0 && TryHandleSerializedObjectReference(writer, value, options, jsonConverter, ref state)) return true; if (jsonConverter != null) { flag = jsonConverter.TryWriteAsObject(writer, value, options, ref state); state.Current.ExitPolymorphicConverter(flag); if (flag && state.Current.IsPushedReferenceForCycleDetection) { state.ReferenceResolver.PopReferenceForCycleDetection(); state.Current.IsPushedReferenceForCycleDetection = false; } return flag; } } state.Push(); flag = OnTryWrite(writer, value, options, ref state); state.Pop(flag); if (flag && state.Current.IsPushedReferenceForCycleDetection) { state.ReferenceResolver.PopReferenceForCycleDetection(); state.Current.IsPushedReferenceForCycleDetection = false; } return flag; } internal bool TryWriteDataExtensionProperty(Utf8JsonWriter writer, T value, JsonSerializerOptions options, ref WriteStack state) { if (!base.IsInternalConverter) return TryWrite(writer, ref value, options, ref state); object obj = this as JsonDictionaryConverter<T>; if (obj == null) { JsonMetadataServicesConverter<T> obj2 = this as JsonMetadataServicesConverter<T>; obj = (((obj2 != null) ? obj2.Converter : null) as JsonDictionaryConverter<T>); } JsonDictionaryConverter<T> jsonDictionaryConverter = (JsonDictionaryConverter<T>)obj; if (jsonDictionaryConverter == null) return TryWrite(writer, ref value, options, ref state); if (writer.CurrentDepth >= options.EffectiveMaxDepth) ThrowHelper.ThrowJsonException_SerializerCycleDetected(options.EffectiveMaxDepth); bool isContinuation = state.IsContinuation; state.Push(); if (!isContinuation) state.Current.OriginalDepth = writer.CurrentDepth; state.Current.IsWritingExtensionDataProperty = true; state.Current.JsonPropertyInfo = state.Current.JsonTypeInfo.ElementTypeInfo.PropertyInfoForTypeInfo; bool flag = jsonDictionaryConverter.OnWriteResume(writer, value, options, ref state); if (flag) VerifyWrite(state.Current.OriginalDepth, writer); state.Pop(flag); return flag; } internal void VerifyRead(JsonTokenType tokenType, int depth, long bytesConsumed, bool isValueConverter, ref Utf8JsonReader reader) { switch (tokenType) { case JsonTokenType.None: break; case JsonTokenType.StartArray: if (reader.TokenType != JsonTokenType.EndArray) ThrowHelper.ThrowJsonException_SerializationConverterRead(this); else if (depth != reader.CurrentDepth) { ThrowHelper.ThrowJsonException_SerializationConverterRead(this); } break; case JsonTokenType.StartObject: if (reader.TokenType != JsonTokenType.EndObject) ThrowHelper.ThrowJsonException_SerializationConverterRead(this); else if (depth != reader.CurrentDepth) { ThrowHelper.ThrowJsonException_SerializationConverterRead(this); } break; default: if (isValueConverter) { if (reader.BytesConsumed != bytesConsumed) ThrowHelper.ThrowJsonException_SerializationConverterRead(this); } else if (!base.CanBePolymorphic && (!base.HandleNullOnRead || tokenType != JsonTokenType.Null)) { ThrowHelper.ThrowJsonException_SerializationConverterRead(this); } break; } } internal void VerifyWrite(int originalDepth, Utf8JsonWriter writer) { if (originalDepth != writer.CurrentDepth) ThrowHelper.ThrowJsonException_SerializationConverterWrite(this); } public abstract void Write(Utf8JsonWriter writer, [System.Runtime.CompilerServices.Nullable(0)] T value, JsonSerializerOptions options); public virtual T ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { JsonConverter<T> fallbackConverterForPropertyNameSerialization = GetFallbackConverterForPropertyNameSerialization(options); if (fallbackConverterForPropertyNameSerialization == null) ThrowHelper.ThrowNotSupportedException_DictionaryKeyTypeNotSupported(Type, this); return fallbackConverterForPropertyNameSerialization.ReadAsPropertyNameCore(ref reader, typeToConvert, options); } internal virtual T ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { long bytesConsumed = reader.BytesConsumed; T result = ReadAsPropertyName(ref reader, typeToConvert, options); if (reader.BytesConsumed != bytesConsumed) ThrowHelper.ThrowJsonException_SerializationConverterRead(this); return result; } public virtual void WriteAsPropertyName(Utf8JsonWriter writer, [System.Diagnostics.CodeAnalysis.DisallowNull] T value, JsonSerializerOptions options) { JsonConverter<T> fallbackConverterForPropertyNameSerialization = GetFallbackConverterForPropertyNameSerialization(options); if (fallbackConverterForPropertyNameSerialization == null) ThrowHelper.ThrowNotSupportedException_DictionaryKeyTypeNotSupported(Type, this); fallbackConverterForPropertyNameSerialization.WriteAsPropertyNameCore(writer, value, options, false); } internal virtual void WriteAsPropertyNameCore(Utf8JsonWriter writer, [System.Diagnostics.CodeAnalysis.DisallowNull] T value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { if (value == null) ThrowHelper.ThrowArgumentNullException("value"); if (isWritingExtensionDataProperty) writer.WritePropertyName((string)(object)value); else { int currentDepth = writer.CurrentDepth; WriteAsPropertyName(writer, value, options); if (currentDepth != writer.CurrentDepth || writer.TokenType != JsonTokenType.PropertyName) ThrowHelper.ThrowJsonException_SerializationConverterWrite(this); } } private JsonConverter<T> GetFallbackConverterForPropertyNameSerialization(JsonSerializerOptions options) { JsonConverter<T> jsonConverter = null; if (!base.IsInternalConverter && !(options.TypeInfoResolver is JsonSerializerContext)) { jsonConverter = _fallbackConverterForPropertyNameSerialization; if (jsonConverter == null && DefaultJsonTypeInfoResolver.TryGetDefaultSimpleConverter(Type, out JsonConverter converter)) jsonConverter = (_fallbackConverterForPropertyNameSerialization = (JsonConverter<T>)converter); } return jsonConverter; } internal virtual T ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling, JsonSerializerOptions options) { throw new InvalidOperationException(); } internal virtual void WriteNumberWithCustomHandling(Utf8JsonWriter writer, T value, JsonNumberHandling handling) { throw new InvalidOperationException(); } } }