Skip to content

System.Text.Json contract customization ignoring custom CreateObject delegates in certain collection types #73382

Description

@eiriktsarpalis

Consider the following code sample:

var options = new JsonSerializerOptions
{
    TypeInfoResolver = new DefaultJsonTypeInfoResolver
    {
        Modifiers =
        {
            static typeInfo =>
            {
                if (typeInfo.Type == typeof(IEnumerable<int>))
                {
                    typeInfo.CreateObject = () => new int[50];
                }
            }
        }
    }
};

var result = JsonSerializer.Deserialize<IEnumerable<int>>("[]");
Console.WriteLine(result is int[]); // Prints "false"

This is because many collection converters are hardcoding their CreateObject implementation which ignores any user-defined delegates:

protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options)
{
if (!_isDeserializable)
{
ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(TypeToConvert, ref reader, ref state);
}
state.Current.ReturnValue = new List<TElement>();
}

Note that this is currently not possible to fix unless we expose an API equivalent to the JsonCollectionConverter.Add method. For .NET 7 we should add detection for converters hardcoding CreateObject/Add implementations to specific types and have the JsonTypeInfo.CreateObject setter throw if not supported by the converter.

Related to #71944.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions