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

JsonSerializerOptions

public sealed class JsonSerializerOptions
Provides options to be used with JsonSerializer.
using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; using System.Text.Encodings.Web; using System.Text.Json.Nodes; using System.Text.Json.Reflection; using System.Text.Json.Serialization; using System.Text.Json.Serialization.Converters; using System.Text.Json.Serialization.Metadata; using System.Threading; namespace System.Text.Json { [System.Runtime.CompilerServices.NullableContext(2)] [System.Runtime.CompilerServices.Nullable(0)] public sealed class JsonSerializerOptions { internal static class TrackedOptionsInstances { public static ConditionalWeakTable<JsonSerializerOptions, object> All { get; } = new ConditionalWeakTable<JsonSerializerOptions, object>(); } private static Dictionary<Type, JsonConverter> s_defaultSimpleConverters; private static JsonConverter[] s_defaultFactoryConverters; private readonly ConcurrentDictionary<Type, JsonConverter> _converters = new ConcurrentDictionary<Type, JsonConverter>(); internal const int BufferSizeDefault = 16384; internal static readonly JsonSerializerOptions s_defaultOptions = new JsonSerializerOptions(); private readonly ConcurrentDictionary<Type, JsonTypeInfo> _classes = new ConcurrentDictionary<Type, JsonTypeInfo>(); internal JsonSerializerContext _context; private Func<Type, JsonSerializerOptions, JsonTypeInfo> _typeInfoCreationFunc; private MemberAccessor _memberAccessorStrategy; private JsonNamingPolicy _dictionaryKeyPolicy; private JsonNamingPolicy _jsonPropertyNamingPolicy; private JsonCommentHandling _readCommentHandling; private ReferenceHandler _referenceHandler; private JavaScriptEncoder _encoder; private JsonIgnoreCondition _defaultIgnoreCondition; private JsonNumberHandling _numberHandling; private JsonUnknownTypeHandling _unknownTypeHandling; private int _defaultBufferSize = 16384; private int _maxDepth; private bool _allowTrailingCommas; private bool _haveTypesBeenCreated; private bool _ignoreNullValues; private bool _ignoreReadOnlyProperties; private bool _ignoreReadonlyFields; private bool _includeFields; private bool _propertyNameCaseInsensitive; private bool _writeIndented; internal ReferenceHandlingStrategy ReferenceHandlingStrategy; [System.Runtime.CompilerServices.Nullable(1)] public IList<JsonConverter> Converters { [System.Runtime.CompilerServices.NullableContext(1)] get; } private JsonTypeInfo _lastClass { get; set; } public bool AllowTrailingCommas { get { return _allowTrailingCommas; } set { VerifyMutable(); _allowTrailingCommas = value; } } public int DefaultBufferSize { get { return _defaultBufferSize; } set { VerifyMutable(); if (value < 1) throw new ArgumentException(System.SR.SerializationInvalidBufferSize); _defaultBufferSize = value; } } public JavaScriptEncoder Encoder { get { return _encoder; } set { VerifyMutable(); _encoder = value; } } public JsonNamingPolicy DictionaryKeyPolicy { get { return _dictionaryKeyPolicy; } set { VerifyMutable(); _dictionaryKeyPolicy = value; } } [System.Obsolete("JsonSerializerOptions.IgnoreNullValues is obsolete. To ignore null values when serializing, set DefaultIgnoreCondition to JsonIgnoreCondition.WhenWritingNull.", DiagnosticId = "SYSLIB0020", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [EditorBrowsable(EditorBrowsableState.Never)] public bool IgnoreNullValues { get { return _ignoreNullValues; } set { VerifyMutable(); if (value && _defaultIgnoreCondition != 0) throw new InvalidOperationException(System.SR.DefaultIgnoreConditionAlreadySpecified); _ignoreNullValues = value; } } public JsonIgnoreCondition DefaultIgnoreCondition { get { return _defaultIgnoreCondition; } set { VerifyMutable(); switch (value) { case JsonIgnoreCondition.Always: throw new ArgumentException(System.SR.DefaultIgnoreConditionInvalid); default: if (_ignoreNullValues) throw new InvalidOperationException(System.SR.DefaultIgnoreConditionAlreadySpecified); break; case JsonIgnoreCondition.Never: break; } _defaultIgnoreCondition = value; } } public JsonNumberHandling NumberHandling { get { return _numberHandling; } set { VerifyMutable(); if (!JsonSerializer.IsValidNumberHandlingValue(value)) throw new ArgumentOutOfRangeException("value"); _numberHandling = value; } } public bool IgnoreReadOnlyProperties { get { return _ignoreReadOnlyProperties; } set { VerifyMutable(); _ignoreReadOnlyProperties = value; } } public bool IgnoreReadOnlyFields { get { return _ignoreReadonlyFields; } set { VerifyMutable(); _ignoreReadonlyFields = value; } } public bool IncludeFields { get { return _includeFields; } set { VerifyMutable(); _includeFields = value; } } public int MaxDepth { get { return _maxDepth; } set { VerifyMutable(); if (value < 0) throw ThrowHelper.GetArgumentOutOfRangeException_MaxDepthMustBePositive("value"); _maxDepth = value; EffectiveMaxDepth = ((value == 0) ? 64 : value); } } internal int EffectiveMaxDepth { get; set; } = 64; public JsonNamingPolicy PropertyNamingPolicy { get { return _jsonPropertyNamingPolicy; } set { VerifyMutable(); _jsonPropertyNamingPolicy = value; } } public bool PropertyNameCaseInsensitive { get { return _propertyNameCaseInsensitive; } set { VerifyMutable(); _propertyNameCaseInsensitive = value; } } public JsonCommentHandling ReadCommentHandling { get { return _readCommentHandling; } set { VerifyMutable(); if ((int)value > 1) throw new ArgumentOutOfRangeException("value", System.SR.JsonSerializerDoesNotSupportComments); _readCommentHandling = value; } } public JsonUnknownTypeHandling UnknownTypeHandling { get { return _unknownTypeHandling; } set { VerifyMutable(); _unknownTypeHandling = value; } } public bool WriteIndented { get { return _writeIndented; } set { VerifyMutable(); _writeIndented = value; } } public ReferenceHandler ReferenceHandler { get { return _referenceHandler; } set { VerifyMutable(); _referenceHandler = value; ReferenceHandlingStrategy = (value?.HandlingStrategy ?? ReferenceHandlingStrategy.None); } } [System.Runtime.CompilerServices.Nullable(1)] internal MemberAccessor MemberAccessorStrategy { get { if (_memberAccessorStrategy == null) _memberAccessorStrategy = new ReflectionEmitMemberAccessor(); return _memberAccessorStrategy; } } internal bool IsInitializedForReflectionSerializer { get; set; } [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.")] private void RootBuiltInConverters() { if (Volatile.Read(ref s_defaultFactoryConverters) == null) { s_defaultSimpleConverters = GetDefaultSimpleConverters(); Volatile.Write(ref s_defaultFactoryConverters, new JsonConverter[8] { new UnsupportedTypeConverterFactory(), new NullableConverterFactory(), new EnumConverterFactory(), new JsonNodeConverterFactory(), new FSharpTypeConverterFactory(), new IAsyncEnumerableConverterFactory(), new IEnumerableConverterFactory(), new ObjectConverterFactory(true) }); } } private static Dictionary<Type, JsonConverter> GetDefaultSimpleConverters() { <>c__DisplayClass4_0 <>c__DisplayClass4_ = default(<>c__DisplayClass4_0); <>c__DisplayClass4_.converters = new Dictionary<Type, JsonConverter>(24); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.BooleanConverter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.ByteConverter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.ByteArrayConverter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.CharConverter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.DateTimeConverter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.DateTimeOffsetConverter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.DoubleConverter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.DecimalConverter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.GuidConverter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.Int16Converter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.Int32Converter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.Int64Converter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(new JsonElementConverter(), ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(new JsonDocumentConverter(), ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.ObjectConverter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.SByteConverter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.SingleConverter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.StringConverter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.TimeSpanConverter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.UInt16Converter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.UInt32Converter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.UInt64Converter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.UriConverter, ref <>c__DisplayClass4_); <GetDefaultSimpleConverters>g__Add|4_0(JsonMetadataServices.VersionConverter, ref <>c__DisplayClass4_); return <>c__DisplayClass4_.converters; } internal JsonConverter DetermineConverter(Type parentClassType, Type runtimePropertyType, MemberInfo memberInfo) { JsonConverter jsonConverter = null; if (memberInfo != (MemberInfo)null) { JsonConverterAttribute jsonConverterAttribute = (JsonConverterAttribute)GetAttributeThatCanHaveMultiple(parentClassType, typeof(JsonConverterAttribute), memberInfo); if (jsonConverterAttribute != null) jsonConverter = GetConverterFromAttribute(jsonConverterAttribute, runtimePropertyType, parentClassType, memberInfo); } if (jsonConverter == null) jsonConverter = GetConverterInternal(runtimePropertyType); JsonConverterFactory jsonConverterFactory = jsonConverter as JsonConverterFactory; if (jsonConverterFactory != null) jsonConverter = jsonConverterFactory.GetConverterInternal(runtimePropertyType, this); if (runtimePropertyType.IsValueType && jsonConverter.IsValueType && (runtimePropertyType.IsNullableOfT() ^ jsonConverter.TypeToConvert.IsNullableOfT())) ThrowHelper.ThrowInvalidOperationException_ConverterCanConvertMultipleTypes(runtimePropertyType, jsonConverter); return jsonConverter; } [System.Runtime.CompilerServices.NullableContext(1)] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Getting a converter for a type may require reflection which depends on unreferenced code.")] public JsonConverter GetConverter(Type typeToConvert) { if (typeToConvert == (Type)null) throw new ArgumentNullException("typeToConvert"); RootBuiltInConverters(); return GetConverterInternal(typeToConvert); } internal JsonConverter GetConverterInternal(Type typeToConvert) { if (_converters.TryGetValue(typeToConvert, out JsonConverter value)) return value; value = _context?.GetTypeInfo(typeToConvert)?.PropertyInfoForTypeInfo?.ConverterBase; foreach (JsonConverter converter in Converters) { if (converter.CanConvert(typeToConvert)) { value = converter; break; } } if (value == null) { JsonConverterAttribute jsonConverterAttribute = (JsonConverterAttribute)GetAttributeThatCanHaveMultiple(typeToConvert, typeof(JsonConverterAttribute)); if (jsonConverterAttribute != null) value = GetConverterFromAttribute(jsonConverterAttribute, typeToConvert, typeToConvert, null); } if (value == null) { if (s_defaultSimpleConverters == null || s_defaultFactoryConverters == null) { ThrowHelper.ThrowNotSupportedException_BuiltInConvertersNotRooted(typeToConvert); return null; } if (s_defaultSimpleConverters.TryGetValue(typeToConvert, out JsonConverter value2)) value = value2; else { JsonConverter[] array = s_defaultFactoryConverters; foreach (JsonConverter jsonConverter in array) { if (jsonConverter.CanConvert(typeToConvert)) { value = jsonConverter; break; } } } } JsonConverterFactory jsonConverterFactory = value as JsonConverterFactory; if (jsonConverterFactory != null) value = jsonConverterFactory.GetConverterInternal(typeToConvert, this); Type typeToConvert2 = value.TypeToConvert; if (!typeToConvert2.IsAssignableFromInternal(typeToConvert) && !typeToConvert.IsAssignableFromInternal(typeToConvert2)) ThrowHelper.ThrowInvalidOperationException_SerializationConverterNotCompatible(value.GetType(), typeToConvert); if (_haveTypesBeenCreated) _converters.TryAdd(typeToConvert, value); return value; } private JsonConverter GetConverterFromAttribute(JsonConverterAttribute converterAttribute, Type typeToConvert, Type classTypeAttributeIsOn, MemberInfo memberInfo) { Type converterType = converterAttribute.ConverterType; JsonConverter jsonConverter; if (converterType == (Type)null) { jsonConverter = converterAttribute.CreateConverter(typeToConvert); if (jsonConverter == null) ThrowHelper.ThrowInvalidOperationException_SerializationConverterOnAttributeNotCompatible(classTypeAttributeIsOn, memberInfo, typeToConvert); } else { ConstructorInfo constructor = converterType.GetConstructor(Type.EmptyTypes); if (!typeof(JsonConverter).IsAssignableFrom(converterType) || constructor == (ConstructorInfo)null || !constructor.IsPublic) ThrowHelper.ThrowInvalidOperationException_SerializationConverterOnAttributeInvalid(classTypeAttributeIsOn, memberInfo); jsonConverter = (JsonConverter)Activator.CreateInstance(converterType); } if (!jsonConverter.CanConvert(typeToConvert)) { Type underlyingType = Nullable.GetUnderlyingType(typeToConvert); if (underlyingType != (Type)null && jsonConverter.CanConvert(underlyingType)) { JsonConverterFactory jsonConverterFactory = jsonConverter as JsonConverterFactory; if (jsonConverterFactory != null) jsonConverter = jsonConverterFactory.GetConverterInternal(underlyingType, this); return NullableConverterFactory.CreateValueConverter(underlyingType, jsonConverter); } ThrowHelper.ThrowInvalidOperationException_SerializationConverterOnAttributeNotCompatible(classTypeAttributeIsOn, memberInfo, typeToConvert); } return jsonConverter; } internal bool TryGetDefaultSimpleConverter(Type typeToConvert, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out JsonConverter converter) { if (_context == null && s_defaultSimpleConverters != null && s_defaultSimpleConverters.TryGetValue(typeToConvert, out converter)) return true; converter = null; return false; } private static Attribute GetAttributeThatCanHaveMultiple(Type classType, Type attributeType, MemberInfo memberInfo) { object[] customAttributes = memberInfo.GetCustomAttributes(attributeType, false); return GetAttributeThatCanHaveMultiple(attributeType, classType, memberInfo, customAttributes); } internal static Attribute GetAttributeThatCanHaveMultiple(Type classType, Type attributeType) { object[] customAttributes = classType.GetCustomAttributes(attributeType, false); return GetAttributeThatCanHaveMultiple(attributeType, classType, null, customAttributes); } private static Attribute GetAttributeThatCanHaveMultiple(Type attributeType, Type classType, MemberInfo memberInfo, object[] attributes) { if (attributes.Length == 0) return null; if (attributes.Length == 1) return (Attribute)attributes[0]; ThrowHelper.ThrowInvalidOperationException_SerializationDuplicateAttribute(attributeType, classType, memberInfo); return null; } public JsonSerializerOptions() { Converters = new ConverterList(this); TrackOptionsInstance(this); } [System.Runtime.CompilerServices.NullableContext(1)] public JsonSerializerOptions(JsonSerializerOptions options) { if (options == null) throw new ArgumentNullException("options"); _memberAccessorStrategy = options._memberAccessorStrategy; _dictionaryKeyPolicy = options._dictionaryKeyPolicy; _jsonPropertyNamingPolicy = options._jsonPropertyNamingPolicy; _readCommentHandling = options._readCommentHandling; _referenceHandler = options._referenceHandler; _encoder = options._encoder; _defaultIgnoreCondition = options._defaultIgnoreCondition; _numberHandling = options._numberHandling; _unknownTypeHandling = options._unknownTypeHandling; _defaultBufferSize = options._defaultBufferSize; _maxDepth = options._maxDepth; _allowTrailingCommas = options._allowTrailingCommas; _ignoreNullValues = options._ignoreNullValues; _ignoreReadOnlyProperties = options._ignoreReadOnlyProperties; _ignoreReadonlyFields = options._ignoreReadonlyFields; _includeFields = options._includeFields; _propertyNameCaseInsensitive = options._propertyNameCaseInsensitive; _writeIndented = options._writeIndented; Converters = new ConverterList(this, (ConverterList)options.Converters); EffectiveMaxDepth = options.EffectiveMaxDepth; ReferenceHandlingStrategy = options.ReferenceHandlingStrategy; TrackOptionsInstance(this); } private static void TrackOptionsInstance(JsonSerializerOptions options) { TrackedOptionsInstances.All.Add(options, null); } public JsonSerializerOptions(JsonSerializerDefaults defaults) : this() { switch (defaults) { case JsonSerializerDefaults.General: break; case JsonSerializerDefaults.Web: _propertyNameCaseInsensitive = true; _jsonPropertyNamingPolicy = JsonNamingPolicy.CamelCase; _numberHandling = JsonNumberHandling.AllowReadingFromString; break; default: throw new ArgumentOutOfRangeException("defaults"); } } [System.Runtime.CompilerServices.NullableContext(0)] public void AddContext<TContext>() where TContext : JsonSerializerContext, new { if (_context != null) ThrowHelper.ThrowInvalidOperationException_JsonSerializerOptionsAlreadyBoundToContext(); (_context = new TContext())._options = this; } [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.")] internal void InitializeForReflectionSerializer() { RootBuiltInConverters(); _typeInfoCreationFunc = ((Type type, JsonSerializerOptions options) => new JsonTypeInfo(type, options)); IsInitializedForReflectionSerializer = true; } internal JsonTypeInfo GetOrAddClass(Type type) { _haveTypesBeenCreated = true; if (TryGetClass(type, out JsonTypeInfo jsonTypeInfo)) return jsonTypeInfo; jsonTypeInfo = _classes.GetOrAdd(type, GetClassFromContextOrCreate(type)); return jsonTypeInfo; } internal JsonTypeInfo GetClassFromContextOrCreate(Type type) { JsonTypeInfo jsonTypeInfo = _context?.GetTypeInfo(type); if (jsonTypeInfo != null) return jsonTypeInfo; if (_typeInfoCreationFunc == null) { ThrowHelper.ThrowNotSupportedException_NoMetadataForType(type); return null; } return _typeInfoCreationFunc(type, this); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal JsonTypeInfo GetOrAddClassForRootType(Type type) { JsonTypeInfo jsonTypeInfo = _lastClass; if (jsonTypeInfo?.Type != type) jsonTypeInfo = (_lastClass = GetOrAddClass(type)); return jsonTypeInfo; } internal bool TryGetClass(Type type, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out JsonTypeInfo jsonTypeInfo) { if (!_classes.TryGetValue(type, out JsonTypeInfo value)) { jsonTypeInfo = null; return false; } jsonTypeInfo = value; return true; } internal bool TypeIsCached(Type type) { return _classes.ContainsKey(type); } internal void ClearClasses() { _classes.Clear(); _lastClass = null; } internal JsonDocumentOptions GetDocumentOptions() { JsonDocumentOptions result = default(JsonDocumentOptions); result.AllowTrailingCommas = AllowTrailingCommas; result.CommentHandling = ReadCommentHandling; result.MaxDepth = MaxDepth; return result; } internal JsonNodeOptions GetNodeOptions() { JsonNodeOptions result = default(JsonNodeOptions); result.PropertyNameCaseInsensitive = PropertyNameCaseInsensitive; return result; } internal JsonReaderOptions GetReaderOptions() { JsonReaderOptions result = default(JsonReaderOptions); result.AllowTrailingCommas = AllowTrailingCommas; result.CommentHandling = ReadCommentHandling; result.MaxDepth = MaxDepth; return result; } internal JsonWriterOptions GetWriterOptions() { JsonWriterOptions result = default(JsonWriterOptions); result.Encoder = Encoder; result.Indented = WriteIndented; result.SkipValidation = true; return result; } internal void VerifyMutable() { if (_haveTypesBeenCreated || _context != null) ThrowHelper.ThrowInvalidOperationException_SerializerOptionsImmutable(_context); } } }