-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Description
Upgrading my project from .netcore 3.1 to .net6 I came across one of my tests failing due to a change in how JsonSerializer.Serialize will serialize an anonymous type.
Reproduction Steps
var obj = new
{
input = new {
foo = "foo"
},
INPUT = new {
foo = "foo"
}
};
var json = JsonSerializer.Serialize(obj); // throws an exceptionExpected behavior
In .netcore 3.1 the above would have returned:
{"input":{"foo":"bar"},"INPUT":{"foo":"bar"}}Actual behavior
In .net5+ this exception is thrown instead:
Unhandled exception. System.InvalidOperationException: Members 'input' and 'INPUT' on type '<>f__AnonymousType2`2[<>f__AnonymousType1`1[System.String],<>f__AnonymousType1`1[System.String]]' cannot both bind with parameter 'input' in the deserialization constructor.
at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_MultiplePropertiesBindToConstructorParameters(Type parentType, String parameterName, String firstMatchName, String secondMatchName)
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.InitializeConstructorParameters(JsonParameterInfoValues[] jsonParameters, Boolean sourceGenMode)
at System.Text.Json.Serialization.Metadata.JsonTypeInfo..ctor(Type type, JsonConverter converter, Type runtimeType, JsonSerializerOptions options)
at System.Text.Json.JsonSerializerOptions.<InitializeForReflectionSerializer>g__CreateJsonTypeInfo|112_0(Type type, JsonSerializerOptions options)
at System.Text.Json.JsonSerializerOptions.GetClassFromContextOrCreate(Type type)
at System.Text.Json.JsonSerializerOptions.GetOrAddClass(Type type)
at System.Text.Json.JsonSerializer.GetTypeInfo(JsonSerializerOptions options, Type runtimeType)
at System.Text.Json.JsonSerializer.Serialize[TValue](TValue value, JsonSerializerOptions options)
Unhandled exception. System.InvalidOperationException: Members 'input' and 'INPUT' on type '<>f__AnonymousType22[<>f__AnonymousType11[System.String],<>f__AnonymousType1`1[System.String]]' cannot both bind with parameter 'input' in the deserialization constructor.
Regression?
Worked as I expected in .netcore 3.1 but not in .net5+
Known Workarounds
If I were to create a class to represent my anonymous type instead, then I do receive the expected JSON string.
public sealed class Obj
{
public Input input {get; set;}
public Input INPUT {get; set;}
}
public sealed class Input
{
public string foo {get;set;}
}And instantiate similar to my anonymous type:
var obj = new Obj()
{
input = new Input()
{
foo="bar"
},
INPUT = new Input()
{
foo="bar"
}
};
var json = JsonSerializer.Serialize(obj);I do get my expected JSON string:
{"input":{"foo":"bar"},"INPUT":{"foo":"bar"}}Configuration
$ dotnet --info
.NET SDK (reflecting any global.json):
Version: 6.0.405
Commit: 27ab36058b
Runtime Environment:
OS Name: debian
OS Version: 11
OS Platform: Linux
RID: debian.11-x64
Base Path: /usr/share/dotnet/sdk/6.0.405/
global.json file:
/workspaces/bipsli/global.json
Host:
Version: 6.0.13
Architecture: x64
Commit: 1af80ba017
.NET SDKs installed:
6.0.405 [/usr/share/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.13 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.13 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Other information
I posted this same question to StackOverflow where it was suggested that I open an issue here.
https://stackoverflow.com/questions/75317065/exception-serializing-anonymous-type-to-json-when-nested-property-names-are-the