Skip to content

Custom JsonConverter breaks context variable in JsonSchemaExporterOptions.TransformSchemaNode callback #109868

@Peter-B-

Description

@Peter-B-

Description

I expect JsonSchemaExporterOptions.TransformSchemaNode to be invoked once for each property of a class. The JsonSchemaExporterContext parameter should be set to the property.

When I add a custom JsonConverter to multiple properties, only the callback for the last property is invoked. It is invoked for each property with a custom JsonConverter.

Reproduction Steps

  • Create two classes C1 and C2
  • Assign a custom JsonConverter to each of these classes
  • Create another class named Test containing a property of each C1 and C2
  • Register a callback to JsonSchemaExporterOptions.TransformSchemaNode
    • Log the context.PropertyInfo and context.TypeInfo

Types

[JsonConverter(typeof(C1JsonConverter))]
public class C1 { }

[JsonConverter(typeof(C2JsonConverter))]
public class C2 { }

public class Test
{
    public C1 C1 { get; set; }
    public C2 C2 { get; set; }
}

Converters

public class C1JsonConverter:JsonConverter<C1>
{
    public override C1? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => 
        new();

    public override void Write(Utf8JsonWriter writer, C1 value, JsonSerializerOptions options) => 
        writer.WriteStringValue("C1");
}

public class C2JsonConverter:JsonConverter<C2>
{
    public override C2? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => 
        new();

    public override void Write(Utf8JsonWriter writer, C2 value, JsonSerializerOptions options) => 
        writer.WriteStringValue("C2");
}

Main

JsonSchemaExporterOptions exporterOptions = new()
{
    TransformSchemaNode = (context, schema) =>
    {
        Console.WriteLine($"Transform {context.TypeInfo.Type.Name} as {context.PropertyInfo?.Name}");

        return schema;
    }
};

var schema = JsonSerializerOptions.Web.GetJsonSchemaAsNode(typeof(Test), exporterOptions);
Console.WriteLine();
Console.WriteLine(schema.ToString());
Console.WriteLine();

Expected behavior

I expect to see one console message for each property:

Transform C1 as c1
Transform C2 as c2
Transform Test as

Actual behavior

The callback is invoked two times with the context of property Test.C2:

Transform C2 as c2
Transform C2 as c2
Transform Test as

Removing one or both of the custom JsonConverters will fix this issue.

Regression?

No response

Known Workarounds

No response

Configuration

  • dotnet SDK 9.0.100
  • Windows 11
  • x64
  • both Debug and Release
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

Other information

No response

Metadata

Metadata

Labels

area-System.Text.Jsonin-prThere is an active PR which will close this issue when it is merged

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions