Repository navigation
Closed
Closed
Copy link
Labels
area-System.Text.JsonenhancementProduct code improvement that does NOT require public API changes/additionsProduct code improvement that does NOT require public API changes/additionspartner-impactThis issue impacts a partner who needs to be kept updatedThis issue impacts a partner who needs to be kept updated
Milestone
Description
Description
Possible regression from #58136, cc. @eiriktsarpalis.
"Records contains a property "EqualityContract" of type Type. This leads to the generator generating serializers for many of the reflection related types as for example Type, ConstructorInfo, MethodInfo, Assembly, Module, etc."
Reproduction Steps
Paste the following code:
public sealed record Test;
[JsonSerializable(typeof(Test))]
public sealed partial class MyTestContext : JsonSerializerContext
{
}Expected behavior
The generated code for Test should not include the "EqualityContract" property.
Actual behavior
// <auto-generated/>
#nullable enable annotations
#nullable disable warnings
// Suppress warnings about [Obsolete] member usage in generated code.
#pragma warning disable CS0618
namespace MyTestProject
{
public sealed partial class MyTestContext
{
private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::MyTestProject.Test>? _Test;
/// <summary>
/// Defines the source generated JSON serialization contract metadata for a given type.
/// </summary>
public global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::MyTestProject.Test> Test
{
get => _Test ??= Create_Test(Options);
}
// Intentionally not a static method because we create a delegate to it. Invoking delegates to instance
// methods is almost as fast as virtual calls. Static methods need to go through a shuffle thunk.
private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::MyTestProject.Test> Create_Test(global::System.Text.Json.JsonSerializerOptions options)
{
global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::MyTestProject.Test>? jsonTypeInfo = null;
global::System.Text.Json.Serialization.JsonConverter? customConverter;
if (options.Converters.Count > 0 && (customConverter = GetRuntimeProvidedCustomConverter(options, typeof(global::MyTestProject.Test))) != null)
{
jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateValueInfo<global::MyTestProject.Test>(options, customConverter);
}
else
{
global::System.Text.Json.Serialization.Metadata.JsonObjectInfoValues<global::MyTestProject.Test> objectInfo = new global::System.Text.Json.Serialization.Metadata.JsonObjectInfoValues<global::MyTestProject.Test>()
{
ObjectCreator = static () => new global::MyTestProject.Test(),
ObjectWithParameterizedConstructorCreator = null,
PropertyMetadataInitializer = _ => TestPropInit(options),
ConstructorParameterMetadataInitializer = null,
NumberHandling = default,
SerializeHandler = TestSerializeHandler
};
jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateObjectInfo<global::MyTestProject.Test>(options, objectInfo);
}
return jsonTypeInfo;
}
private static global::System.Text.Json.Serialization.Metadata.JsonPropertyInfo[] TestPropInit(global::System.Text.Json.JsonSerializerOptions options)
{
global::System.Text.Json.Serialization.Metadata.JsonPropertyInfo[] properties = new global::System.Text.Json.Serialization.Metadata.JsonPropertyInfo[1];
global::System.Text.Json.Serialization.Metadata.JsonPropertyInfoValues<global::System.Type> info0 = new global::System.Text.Json.Serialization.Metadata.JsonPropertyInfoValues<global::System.Type>()
{
IsProperty = true,
IsPublic = false,
IsVirtual = false,
DeclaringType = typeof(global::MyTestProject.Test),
Converter = null,
Getter = null,
Setter = null,
IgnoreCondition = null,
HasJsonInclude = false,
IsExtensionData = false,
NumberHandling = default,
PropertyName = "EqualityContract",
JsonPropertyName = null
};
global::System.Text.Json.Serialization.Metadata.JsonPropertyInfo propertyInfo0 = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreatePropertyInfo<global::System.Type>(options, info0);
properties[0] = propertyInfo0;
return properties;
}
private void TestSerializeHandler(global::System.Text.Json.Utf8JsonWriter writer, global::MyTestProject.Test? value)
{
if (value == null)
{
writer.WriteNullValue();
return;
}
writer.WriteStartObject();
writer.WriteEndObject();
}
}
}Regression?
Seems like it might be the case, yes. I'm using 7.0.0-rc.2.22472.3.
Known Workarounds
None.
Configuration
.NET Standard 2.0 class library, using System.Text.Json 7.0.0-rc.2.22472.3.
Metadata
Metadata
Assignees
Labels
area-System.Text.JsonenhancementProduct code improvement that does NOT require public API changes/additionsProduct code improvement that does NOT require public API changes/additionspartner-impactThis issue impacts a partner who needs to be kept updatedThis issue impacts a partner who needs to be kept updated
Activity
layomia commentedon Nov 1, 2022
I was able to repro. Just to explicitly state the distinction here vs #58136:
We do have a change where the "EqualityContract" property is included in the list of
JsonPropertyInfoValueswhen creatingJsonTypeInfoinstances for record types, but unlike the other issue we are not generating metadata forSystem.Type's members. The change in generated output should have minimal impact to assembly size, and has no impact to actual JSON (de)serialization AFAICT. Thus I don't think it needs to be addressed for .NET 7.cc @krwq @eiriktsarpalis do you know why this property is being added (say a side effect of contract generation changes in 7.0)?
eiriktsarpalis commentedon Nov 1, 2022
I checked and it seems this property is also being added in .NET 6, so based on the feedback in #58136 there might have been a change/regression in .NET 6 GA. Further investigation is needed to determine if and why such a change was made.
eiriktsarpalis commentedon Nov 1, 2022
Related to #66679, as they both seem to stem from us not honoring
protectedaccessibility modifiers (EqualityContractis a compiler-generated protected property).Sergio0694 commentedon Dec 3, 2022
@eiriktsarpalis Just for additional context, this is also one of the group of issues we're hitting in the Microsoft Store, should we add
partner-impacthere too so that they're all better classified with respect this? Thank you! 😄