| File: System\Text\Json\Serialization\JsonSerializerContext.cs | Web Access |
| Project: src\runtime\src\libraries\System.Text.Json\src\System.Text.Json.csproj (System.Text.Json) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; using System.Text.Json.Serialization.Metadata; namespace System.Text.Json.Serialization { /// <summary> /// Provides metadata about a set of types that is relevant to JSON serialization. /// </summary> public abstract partial class JsonSerializerContext : IJsonTypeInfoResolver, IBuiltInJsonTypeInfoResolver { private JsonSerializerOptions? _options; /// <summary> /// Gets the run time specified options of the context. If no options were passed /// when instantiating the context, then a new instance is bound and returned. /// </summary> /// <remarks> /// The options instance cannot be mutated once it is bound to the context instance. /// </remarks> public JsonSerializerOptions Options { get { JsonSerializerOptions? options = _options; if (options is null) { options = new JsonSerializerOptions { TypeInfoResolver = this }; options.MakeReadOnly(); _options = options; } return options; } } internal void AssociateWithOptions(JsonSerializerOptions options) { Debug.Assert(!options.IsReadOnly); options.TypeInfoResolver = this; options.MakeReadOnly(); _options = options; } /// <summary> /// Indicates whether pre-generated serialization logic for types in the context /// is compatible with the run time specified <see cref="JsonSerializerOptions"/>. /// </summary> bool IBuiltInJsonTypeInfoResolver.IsCompatibleWithOptions(JsonSerializerOptions options) { Debug.Assert(options != null); JsonSerializerOptions? generatedSerializerOptions = GeneratedSerializerOptions; return generatedSerializerOptions is not null && // Guard against unsupported features options.Converters.Count == 0 && options.Encoder is null && // Disallow custom number handling we'd need to honor when writing. // AllowReadingFromString and Strict are fine since there's no action to take when writing. !JsonHelpers.RequiresSpecialNumberHandlingOnWrite(options.NumberHandling) && options.ReferenceHandlingStrategy == JsonKnownReferenceHandler.Unspecified && #pragma warning disable SYSLIB0020 !options.IgnoreNullValues && // This property is obsolete. #pragma warning restore SYSLIB0020 // Ensure options values are consistent with expected defaults. options.DefaultIgnoreCondition == generatedSerializerOptions.DefaultIgnoreCondition && options.RespectNullableAnnotations == generatedSerializerOptions.RespectNullableAnnotations && options.IgnoreReadOnlyFields == generatedSerializerOptions.IgnoreReadOnlyFields && options.IgnoreReadOnlyProperties == generatedSerializerOptions.IgnoreReadOnlyProperties && options.IncludeFields == generatedSerializerOptions.IncludeFields && options.PropertyNamingPolicy == generatedSerializerOptions.PropertyNamingPolicy && options.DictionaryKeyPolicy is null; } /// <summary> /// The default run time options for the context. Its values are defined at design-time via <see cref="JsonSourceGenerationOptionsAttribute"/>. /// </summary> protected abstract JsonSerializerOptions? GeneratedSerializerOptions { get; } /// <summary> /// Creates an instance of <see cref="JsonSerializerContext"/> and binds it with the indicated <see cref="JsonSerializerOptions"/>. /// </summary> /// <param name="options">The run time provided options for the context instance.</param> /// <remarks> /// If no instance options are passed, then no options are set until the context is bound using <see cref="JsonSerializerOptions.AddContext{TContext}"/>, /// or until <see cref="Options"/> is called, where a new options instance is created and bound. /// </remarks> protected JsonSerializerContext(JsonSerializerOptions? options) { if (options != null) { options.VerifyMutable(); AssociateWithOptions(options); } } /// <summary> /// Returns a <see cref="JsonTypeInfo"/> instance representing the given type. /// </summary> /// <param name="type">The type to fetch metadata about.</param> /// <returns>The metadata for the specified type, or <see langword="null" /> if the context has no metadata for the type.</returns> public abstract JsonTypeInfo? GetTypeInfo(Type type); JsonTypeInfo? IJsonTypeInfoResolver.GetTypeInfo(Type type, JsonSerializerOptions options) { if (options != null && options != _options) { ThrowHelper.ThrowInvalidOperationException_ResolverTypeInfoOptionsNotCompatible(); } return GetTypeInfo(type); } } }