Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Tracked by #71944
eiriktsarpalis opened this issue Aug 4, 2022 · 1 comment

Comments

@eiriktsarpalis
Copy link
Member

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.

@ghost
Copy link

ghost commented Aug 4, 2022

Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis
See info in area-owners.md if you want to be subscribed.

Issue Details

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.

Author: eiriktsarpalis
Assignees: -
Labels:

bug, area-System.Text.Json

Milestone: 8.0.0

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

No branches or pull requests

2 participants