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

JsonConverter

public abstract class JsonConverter
Converts an object or value to or from JSON.
using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; using System.Text.Json.Serialization.Converters; using System.Text.Json.Serialization.Metadata; namespace System.Text.Json.Serialization { [System.Runtime.CompilerServices.NullableContext(2)] [System.Runtime.CompilerServices.Nullable(0)] public abstract class JsonConverter { private ConverterStrategy _converterStrategy; public abstract Type Type { get; } internal ConverterStrategy ConverterStrategy { get { return _converterStrategy; } set { CanUseDirectReadOrWrite = (value == ConverterStrategy.Value && IsInternalConverter); RequiresReadAhead = (value == ConverterStrategy.Value); _converterStrategy = value; } } internal virtual bool SupportsCreateObjectDelegate => false; internal virtual bool CanPopulate => false; internal bool CanUseDirectReadOrWrite { get; set; } internal virtual bool CanHaveMetadata => false; internal bool CanBePolymorphic { get; set; } internal bool RequiresReadAhead { get; set; } internal bool UsesDefaultHandleNull { get; set; } internal bool HandleNullOnRead { get; set; } internal bool HandleNullOnWrite { get; set; } internal virtual JsonConverter SourceConverterForCastingConverter => null; internal abstract Type ElementType { get; } internal abstract Type KeyType { get; } internal bool IsValueType { get; set; } internal bool IsInternalConverter { get; set; } internal bool IsInternalConverterForNumberType { get; set; } internal virtual bool ConstructorIsParameterized { get; } internal ConstructorInfo ConstructorInfo { get; set; } internal JsonConverter() { IsInternalConverter = (GetType().Assembly == typeof(JsonConverter).Assembly); ConverterStrategy = GetDefaultConverterStrategy(); } [System.Runtime.CompilerServices.NullableContext(1)] public abstract bool CanConvert(Type typeToConvert); private protected abstract ConverterStrategy GetDefaultConverterStrategy(); internal virtual void ReadElementAndSetProperty(object obj, string propertyName, ref Utf8JsonReader reader, JsonSerializerOptions options, [System.Runtime.CompilerServices.ScopedRef] ref ReadStack state) { throw new InvalidOperationException(); } internal virtual JsonTypeInfo CreateJsonTypeInfo(JsonSerializerOptions options) { throw new InvalidOperationException(); } internal JsonConverter<TTarget> CreateCastingConverter<TTarget>() { JsonConverter<TTarget> jsonConverter = this as JsonConverter<TTarget>; if (jsonConverter != null) return jsonConverter; JsonSerializerOptions.CheckConverterNullabilityIsSameAsPropertyType(this, typeof(TTarget)); return SourceConverterForCastingConverter?.CreateCastingConverter<TTarget>() ?? new CastingConverter<TTarget>(this); } internal static bool ShouldFlush(Utf8JsonWriter writer, ref WriteStack state) { if (state.FlushThreshold > 0) return writer.BytesPending > state.FlushThreshold; return false; } internal abstract object ReadAsObject(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options); internal abstract bool OnTryReadAsObject(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, [System.Runtime.CompilerServices.ScopedRef] ref ReadStack state, out object value); internal abstract bool TryReadAsObject(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, [System.Runtime.CompilerServices.ScopedRef] ref ReadStack state, out object value); internal abstract object ReadAsPropertyNameAsObject(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options); internal abstract object ReadAsPropertyNameCoreAsObject(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options); internal abstract object ReadNumberWithCustomHandlingAsObject(ref Utf8JsonReader reader, JsonNumberHandling handling, JsonSerializerOptions options); internal abstract void WriteAsObject(Utf8JsonWriter writer, object value, JsonSerializerOptions options); internal abstract bool OnTryWriteAsObject(Utf8JsonWriter writer, object value, JsonSerializerOptions options, ref WriteStack state); internal abstract bool TryWriteAsObject(Utf8JsonWriter writer, object value, JsonSerializerOptions options, ref WriteStack state); internal abstract void WriteAsPropertyNameAsObject(Utf8JsonWriter writer, object value, JsonSerializerOptions options); internal abstract void WriteAsPropertyNameCoreAsObject(Utf8JsonWriter writer, object value, JsonSerializerOptions options, bool isWritingExtensionDataProperty); internal abstract void WriteNumberWithCustomHandlingAsObject(Utf8JsonWriter writer, object value, JsonNumberHandling handling); internal virtual void ConfigureJsonTypeInfo(JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options) { } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] internal virtual void ConfigureJsonTypeInfoUsingReflection(JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options) { } internal JsonConverter ResolvePolymorphicConverter(JsonTypeInfo jsonTypeInfo, ref ReadStack state) { JsonConverter jsonConverter = null; switch (state.Current.PolymorphicSerializationState) { case PolymorphicSerializationState.None: { PolymorphicTypeResolver polymorphicTypeResolver = jsonTypeInfo.PolymorphicTypeResolver; if (polymorphicTypeResolver.TryGetDerivedJsonTypeInfo(state.PolymorphicTypeDiscriminator, out JsonTypeInfo jsonTypeInfo2)) { jsonConverter = state.InitializePolymorphicReEntry(jsonTypeInfo2); if (!jsonConverter.CanHaveMetadata) ThrowHelper.ThrowNotSupportedException_DerivedConverterDoesNotSupportMetadata(jsonTypeInfo2.Type); } else state.Current.PolymorphicSerializationState = PolymorphicSerializationState.PolymorphicReEntryNotFound; state.PolymorphicTypeDiscriminator = null; break; } case PolymorphicSerializationState.PolymorphicReEntrySuspended: jsonConverter = state.ResumePolymorphicReEntry(); break; } return jsonConverter; } internal JsonConverter ResolvePolymorphicConverter(object value, JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options, ref WriteStack state) { JsonConverter jsonConverter = null; switch (state.Current.PolymorphicSerializationState) { case PolymorphicSerializationState.None: { Type type = value.GetType(); if (CanBePolymorphic && type != Type) { jsonTypeInfo = state.Current.InitializePolymorphicReEntry(type, options); jsonConverter = jsonTypeInfo.Converter; } PolymorphicTypeResolver polymorphicTypeResolver = jsonTypeInfo.PolymorphicTypeResolver; if (polymorphicTypeResolver != null && polymorphicTypeResolver.TryGetDerivedJsonTypeInfo(type, out JsonTypeInfo jsonTypeInfo2, out object typeDiscriminator)) { jsonConverter = state.Current.InitializePolymorphicReEntry(jsonTypeInfo2); if (typeDiscriminator != null) { if (!jsonConverter.CanHaveMetadata) ThrowHelper.ThrowNotSupportedException_DerivedConverterDoesNotSupportMetadata(jsonTypeInfo2.Type); state.PolymorphicTypeDiscriminator = typeDiscriminator; state.PolymorphicTypeResolver = polymorphicTypeResolver; } } if (jsonConverter == null) state.Current.PolymorphicSerializationState = PolymorphicSerializationState.PolymorphicReEntryNotFound; break; } case PolymorphicSerializationState.PolymorphicReEntrySuspended: jsonConverter = state.Current.ResumePolymorphicReEntry(); break; } return jsonConverter; } internal bool TryHandleSerializedObjectReference(Utf8JsonWriter writer, object value, JsonSerializerOptions options, JsonConverter polymorphicConverter, ref WriteStack state) { switch (options.ReferenceHandlingStrategy) { case ReferenceHandlingStrategy.IgnoreCycles: { ReferenceResolver referenceResolver = state.ReferenceResolver; if (referenceResolver.ContainsReferenceForCycleDetection(value)) { writer.WriteNullValue(); return true; } referenceResolver.PushReferenceForCycleDetection(value); state.Current.IsPushedReferenceForCycleDetection = (state.CurrentDepth > 0); break; } case ReferenceHandlingStrategy.Preserve: if ((polymorphicConverter?.CanHaveMetadata ?? CanHaveMetadata) && JsonSerializer.TryGetReferenceForValue(value, ref state, writer)) return true; break; } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool SingleValueReadWithReadAhead(bool requiresReadAhead, ref Utf8JsonReader reader, [System.Runtime.CompilerServices.ScopedRef] ref ReadStack state) { if (!requiresReadAhead || !state.ReadAhead) return reader.Read(); return DoSingleValueReadWithReadAhead(ref reader); } internal static bool DoSingleValueReadWithReadAhead(ref Utf8JsonReader reader) { Utf8JsonReader utf8JsonReader = reader; if (!reader.Read()) return false; JsonTokenType tokenType = reader.TokenType; if ((tokenType == JsonTokenType.StartObject || tokenType == JsonTokenType.StartArray) ? true : false) { bool flag = reader.TrySkip(); reader = utf8JsonReader; if (!flag) return false; ref reader.ReadWithVerify(); } return true; } } }