Skip to content

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

@eiriktsarpalis

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions