Skip to content

The JsonSerializerOptions.TypeInfoResolver property should be nullable #71960

Closed
@eiriktsarpalis

Description

@eiriktsarpalis

The current iteration of JsonSerializerOptions.TypeInfoResolver

public IJsonTypeInfoResolver TypeInfoResolver
{
[RequiresUnreferencedCode(JsonSerializer.SerializationUnreferencedCodeMessage)]
[RequiresDynamicCode(JsonSerializer.SerializationRequiresDynamicCodeMessage)]
get
{
return _typeInfoResolver ??= DefaultJsonTypeInfoResolver.RootDefaultInstance();
}
set
{
VerifyMutable();
_typeInfoResolver = value;
}
}

is implemented as non-nullable and marked as RequiredUnreferencedCode since by default it will return the reflection-based contract resolver. This has been informed by the existing semantics of the JsonSerializer methods accepting JsonSerializerOptions as an argument: unless a contract resolver is explicitly set the method will revert to using reflection-based serialization.

I believe however that this approach is problematic, for a number of reasons:

  • Because the property is marked RUC, it can trigger linker warnings in otherwise innocuous operations, such as copying resolver configuration to a new options instance.
  • The introduction of contract customization has effectively decoupled reflection-based serialization from JsonSerializerOptions. While we cannot change the semantics of existing JsonSerializer methods it is conceivable that future serialization APIs can make use of it in a linker-safe manner. Assuming we ship the TypeInfoResolver property in the current manifestation, we forever couple JsonSerializerOptions to the reflection-based serialization and trimmability concerns.

I propose we make the following changes to the API:

public partial class JsonSerializerOptions
{
-       [RequiresUnreferenceCode]
-       [RequiresDynamicCode]
-       public IJsonTypeInfoResolver TypeInfoResolver { get; set; }
+       public IJsonTypeInfoResolver? TypeInfoResolver { get; set; }

+       [RequiresUnreferenceCode]
+       [RequiresDynamicCode]
        public static JsonSerializerOptions Default { get; } // default instance comes populated with reflection resolver
}

Metadata

Metadata

Labels

area-System.Text.JsonenhancementProduct code improvement that does NOT require public API changes/additions

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions