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.JsonSerializer does not work with Dictionary<string, object> #67588

Closed
Tracked by #63918
konarx opened this issue Apr 5, 2022 · 3 comments · Fixed by #67618
Closed
Tracked by #63918

System.Text.Json.JsonSerializer does not work with Dictionary<string, object> #67588

konarx opened this issue Apr 5, 2022 · 3 comments · Fixed by #67618
Assignees
Milestone

Comments

@konarx
Copy link

konarx commented Apr 5, 2022

Description

When a Dictionary<string, object> needs serialization, the .NET default System.Text.Json.JsonSerializer throws an exception:

System.InvalidOperationException: Method may only be called on a Type for which Type.IsGenericParameter is true.

I have provided a simple piece of code example to reproduce it. I tried with Newtonsoft.Json.JsonConvert and it works flawlessly.

Reproduction Steps

 public void TestDictionarySerialize()
        {
            var dictionary = new Dictionary<string, object> {
                {"Hello", typeof(string)}, 
                {"World", typeof(string)}
            };

            //This serialization fails
            System.Text.Json.JsonSerializer.Serialize(dictionary,
                typeof(Dictionary<string, object>));

           //This serialization fails
            System.Text.Json.JsonSerializer.Serialize(dictionary);

            //This serialization succeeds
            Newtonsoft.Json.JsonConvert.SerializeObject(dictionary);
        }

Expected behavior

System.Text.Json.JsonSerializer should not throw any Exception

Actual behavior

System.Text.Json.JsonSerializer throws:

System.InvalidOperationException: Method may only be called on a Type for which Type.IsGenericParameter is true.

Regression?

No response

Known Workarounds

Newtonsoft.Json.JsonConvert works flawlessly

Configuration

  • .NET 6.0.200
  • Windows 10 Enterprise 21H2 19044.1586
  • x64

Other information

No response

@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Text.Json untriaged New issue has not been triaged by the area owner labels Apr 5, 2022
@ghost
Copy link

ghost commented Apr 5, 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

Description

When a Dictionary<string, object> needs serialization, the .NET default System.Text.Json.JsonSerializer throws an exception:

System.InvalidOperationException: Method may only be called on a Type for which Type.IsGenericParameter is true.

I have provided a simple piece of code example to reproduce it. I tried with Newtonsoft.Json.JsonConvert and it works flawlessly.

Reproduction Steps

 public void TestDictionarySerialize()
        {
            var dictionary = new Dictionary<string, object> {
                {"Hello", typeof(string)}, 
                {"World", typeof(string)}
            };

            //This serialization fails
            System.Text.Json.JsonSerializer.Serialize(dictionary,
                typeof(Dictionary<string, object>));

            //This serialization succeeds
            Newtonsoft.Json.JsonConvert.SerializeObject(dictionary);
        }

Expected behavior

System.Text.Json.JsonSerializer should not throw any Exception

Actual behavior

System.Text.Json.JsonSerializer throws:

System.InvalidOperationException: Method may only be called on a Type for which Type.IsGenericParameter is true.

Regression?

No response

Known Workarounds

Newtonsoft.Json.JsonConvert works flawlessly

Configuration

  • .NET 6.0.200
  • Windows 10 Enterprise 21H2 19044.1586
  • x64

Other information

No response

Author: konarx
Assignees: -
Labels:

area-System.Text.Json, untriaged

Milestone: -

@danmoseley
Copy link
Member

 	System.Private.CoreLib.dll!System.RuntimeType.DeclaringMethod.get() Line 3214	C#
>	System.Text.Json.dll!System.Text.Json.Serialization.Metadata.JsonPropertyInfo<System.Reflection.MethodBase>.GetMemberAndWriteJson(object obj, ref System.Text.Json.WriteStack state, System.Text.Json.Utf8JsonWriter writer) Line 247	C#
 	System.Text.Json.dll!System.Text.Json.Serialization.Converters.ObjectDefaultConverter<System.RuntimeType>.OnTryWrite(System.Text.Json.Utf8JsonWriter writer, System.RuntimeType value, System.Text.Json.JsonSerializerOptions options, ref System.Text.Json.WriteStack state) Line 289	C#
 	System.Text.Json.dll!System.Text.Json.Serialization.JsonConverter<System.RuntimeType>.TryWrite(System.Text.Json.Utf8JsonWriter writer, System.RuntimeType value, System.Text.Json.JsonSerializerOptions options, ref System.Text.Json.WriteStack state) Line 473	C#
 	System.Text.Json.dll!System.Text.Json.Serialization.JsonConverter<System.RuntimeType>.TryWriteAsObject(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options, ref System.Text.Json.WriteStack state) Line 118	C#
 	System.Text.Json.dll!System.Text.Json.Serialization.JsonConverter<System.__Canon>.TryWrite(System.Text.Json.Utf8JsonWriter writer, System.__Canon value, System.Text.Json.JsonSerializerOptions options, ref System.Text.Json.WriteStack state) Line 413	C#
 	System.Text.Json.dll!System.Text.Json.Serialization.Converters.DictionaryOfTKeyTValueConverter<System.Collections.Generic.Dictionary<string, object>, string, object>.OnWriteResume(System.Text.Json.Utf8JsonWriter writer, System.Collections.Generic.Dictionary<string, object> value, System.Text.Json.JsonSerializerOptions options, ref System.Text.Json.WriteStack state) Line 87	C#
 	System.Text.Json.dll!System.Text.Json.Serialization.JsonDictionaryConverter<System.__Canon, System.__Canon, System.__Canon>.OnTryWrite(System.Text.Json.Utf8JsonWriter writer, System.__Canon dictionary, System.Text.Json.JsonSerializerOptions options, ref System.Text.Json.WriteStack state) Line 302	C#
 	System.Text.Json.dll!System.Text.Json.Serialization.JsonConverter<System.Collections.Generic.Dictionary<string, object>>.TryWrite(System.Text.Json.Utf8JsonWriter writer, System.Collections.Generic.Dictionary<string, object> value, System.Text.Json.JsonSerializerOptions options, ref System.Text.Json.WriteStack state) Line 473	C#
 	System.Text.Json.dll!System.Text.Json.Serialization.JsonConverter<System.__Canon>.WriteCore(System.Text.Json.Utf8JsonWriter writer, System.__Canon value, System.Text.Json.JsonSerializerOptions options, ref System.Text.Json.WriteStack state) Line 41	C#
 	System.Text.Json.dll!System.Text.Json.Serialization.JsonConverter<System.Collections.Generic.Dictionary<string, object>>.WriteCoreAsObject(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options, ref System.Text.Json.WriteStack state) Line 30	C#
 	System.Text.Json.dll!System.Text.Json.JsonSerializer.WriteUsingSerializer<object>(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) Line 85	C#
 	System.Text.Json.dll!System.Text.Json.JsonSerializer.WriteStringUsingSerializer<object>(object value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) Line 155	C#
 	System.Text.Json.dll!System.Text.Json.JsonSerializer.Serialize(object value, System.Type inputType, System.Text.Json.JsonSerializerOptions options) Line 63	C#
 	ConsoleApp43.dll!Program.<Main>$(string[] args) Line 7	C#

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Apr 5, 2022
@eiriktsarpalis eiriktsarpalis added bug and removed untriaged New issue has not been triaged by the area owner labels Apr 5, 2022
@eiriktsarpalis
Copy link
Member

eiriktsarpalis commented Apr 5, 2022

This is a bug, our unsupported type detection for System.Type values is evaded in the case of polymorphism. Values are resolved as System.RuntimeType which is not caught by the relevant converter.

This example should have failed with NotSupportedException since System.Type serialization is not supported by default.

@eiriktsarpalis eiriktsarpalis self-assigned this Apr 5, 2022
@eiriktsarpalis eiriktsarpalis added this to the 7.0.0 milestone Apr 5, 2022
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Apr 12, 2022
@ghost ghost locked as resolved and limited conversation to collaborators May 12, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
3 participants