Skip to content

Breaking change: Untyped Deserialize no longer forwards the type to JsonConverter<T> #77173

@bjuris

Description

@bjuris

Description

When calling JsonSerializer.Deserialize(json, type, option) with a converter the type sent to the converter is hardcoded to the type defined in the converter, and not what was sent to the method.

In this method typeToConvert will always be T in JsonConverter<T>.

public override BlockData Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)

System.Text.Json .NET 6 implementation:
bool success = TryRead(ref reader, jsonPropertyInfo.RuntimePropertyType!, options, ref state, out T? value);
https://github.com/dotnet/runtime/blob/v6.0.10/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.ReadCore.cs#L62

System.Text.Json .NET 7 implementation:
bool success = TryRead(ref reader, TypeToConvert, options, ref state, out T? value);
https://github.com/dotnet/runtime/blob/main/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.ReadCore.cs#L61

Reproduction Steps

using System.Text.Json;
using System.Text.Json.Serialization;

var o = new JsonSerializerOptions();
o.Converters.Add(new C());
var x = JsonSerializer.Deserialize("{}", typeof(B), o);
Console.WriteLine("Output was: " + x.GetType());

public class A
{ }
public class B : A
{ }

public class C : JsonConverter<A>
{
    public override bool CanConvert(Type typeToConvert)
    {
        return typeof(A).IsAssignableFrom(typeToConvert);
    }
    public override A? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        reader.Read();
        Console.WriteLine("Converter sees: " + typeToConvert);
        return (A)Activator.CreateInstance(typeToConvert);
    }

    public override void Write(Utf8JsonWriter writer, A value, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }
}

Output on .NET 6:

Converter sees: B
Output was: B

Output on .NET 7:

Converter sees: A
Output was: A

Expected behavior

Type sent to Deserialized should be sent to converter.

Actual behavior

Type sent to Deserialized is not sent to converter.

Regression?

This works in .NET 6, but not .NET 7.

Known Workarounds

No response

Configuration

Windows x64, 6.0.400 vs 7.0.100-rc.2.22477.23

Other information

No response

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions