Skip to content

options.GetConverter used inside other JsonConverter causes "Deserialization of types without[...]" error #94538

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

Closed
raphaelschmitz00 opened this issue Nov 8, 2023 · 2 comments

Comments

@raphaelschmitz00
Copy link

Description

Getting a converter via GetConverter() and using it inside another JsonConverter throws a NotSupportedException.

Reproduction Steps

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


public class TestDocument
{
	public TestType TestType { get; init; }
}


public class TestType { }


public class TestConverter : JsonConverter<TestType>
{
	private readonly JsonConverter<TestType> _innerConverter;
	
	public TestConverter(JsonConverter<TestType> innerConverter)
	{
		_innerConverter = innerConverter;
	}
	
	public override TestType? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => 
		_innerConverter.Read(ref reader, typeToConvert, options);
	
	public override void Write(Utf8JsonWriter writer, TestType value, JsonSerializerOptions options) => 
		throw new NotImplementedException();
}


public class InnerConverterTests
{
	[Fact]
	public void InnerConverter_Works()
	{
		var json = """{ "TestType": {} }""";
		
		var options = new JsonSerializerOptions();
		var innerConverter = (JsonConverter<TestType>)options.GetConverter(typeof(TestType));
		var testConverter = new TestConverter(innerConverter);
		options.Converters.Add(testConverter);

		// This next line produces the error
		var testDocument = JsonSerializer.Deserialize<TestDocument>(json, options);
	}
}

Expected behavior

With the given example, "standard" deserialization, as if I didn't provide any JsonSerializerOptions.

Actual behavior

Throws a System.NotSupportedException with message "Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported."

Maybe this is a weird thing to do, but the error message is at least still misleading then.

Regression?

I don't know.

Known Workarounds

No response

Configuration

.NET 7.0.401
win11
x64

Other information

No response

@ghost ghost added area-System.Text.Json untriaged New issue has not been triaged by the area owner labels Nov 8, 2023
@ghost
Copy link

ghost commented Nov 8, 2023

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

Description

Getting a converter via GetConverter() and using it inside another JsonConverter throws a NotSupportedException.

Reproduction Steps

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


public class TestDocument
{
	public TestType TestType { get; init; }
}


public class TestType { }


public class TestConverter : JsonConverter<TestType>
{
	private readonly JsonConverter<TestType> _innerConverter;
	
	public TestConverter(JsonConverter<TestType> innerConverter)
	{
		_innerConverter = innerConverter;
	}
	
	public override TestType? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => 
		_innerConverter.Read(ref reader, typeToConvert, options);
	
	public override void Write(Utf8JsonWriter writer, TestType value, JsonSerializerOptions options) => 
		throw new NotImplementedException();
}


public class InnerConverterTests
{
	[Fact]
	public void InnerConverter_Works()
	{
		var json = """{ "TestType": {} }""";
		
		var options = new JsonSerializerOptions();
		var innerConverter = (JsonConverter<TestType>)options.GetConverter(typeof(TestType));
		var testConverter = new TestConverter(innerConverter);
		options.Converters.Add(testConverter);

		// This next line produces the error
		var testDocument = JsonSerializer.Deserialize<TestDocument>(json, options);
	}
}

Expected behavior

With the given example, "standard" deserialization, as if I didn't provide any JsonSerializerOptions.

Actual behavior

Throws a System.NotSupportedException with message "Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported."

Maybe this is a weird thing to do, but the error message is at least still misleading then.

Regression?

I don't know.

Known Workarounds

No response

Configuration

.NET 7.0.401
win11
x64

Other information

No response

Author: raphaelschmitz00
Assignees: -
Labels:

area-System.Text.Json

Milestone: -

@eiriktsarpalis
Copy link
Member

This is a known problem, unfortunately certain built-in converters cannot function independently of contract metadata. As a workaround you could try wrapping the JsonTypeInfo<T> instance for the particular type which encapsulates both the converter and the required contract metadata:

var innerTypeInfo = (JsonTypeInfo<TestType>)JsonSerializerOptions.Default.GetTypeInfo(typeof(TestType));
var options = new JsonSerializerOptions
{
    Converters = { new TestConverter(innerTypeInfo) }
};

JsonSerializer.Deserialize<TestDocument>(json, options);

public class TestConverter : JsonConverter<TestType>
{
    private readonly JsonTypeInfo<TestType> _innerTypeInfo;

    public TestConverter(JsonTypeInfo<TestType> innerTypeInfo)
    {
        _innerTypeInfo = innerTypeInfo;
    }

    public override TestType? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
        JsonSerializer.Deserialize(ref reader, _innerTypeInfo);

    public override void Write(Utf8JsonWriter writer, TestType value, JsonSerializerOptions options) =>
        throw new NotImplementedException();
}

Duplicate of #50205.

@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Nov 8, 2023
@github-actions github-actions bot locked and limited conversation to collaborators Dec 9, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants