Open mikekistler opened 4 weeks ago
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis See info in area-owners.md if you want to be subscribed.
I suspect this is related to the discriminator id conflicting with a property of a similar name, although I couldn't reproduce the error in the standalone JsonSchemaMapper
component. @captainsafia I'm assuming this could be caused by the fixup logic performed by the callback, but I defer to you on that. It may well be that the issue has resolved itself in Preview 6 since JsonSchemaMapper
was replaced with the built-in STJ exporter.
@eiriktsarpalis I was actually able to repro this in the new codebase that doesn't use the JsconSchemaMapper
prototype.
I was able to repro this without the custom TransformSchemaNode
callback registered in the callback:
[JsonPolymorphic(TypeDiscriminatorPropertyName = "shapeType")]
[JsonDerivedType(typeof(AnotherTriangle), typeDiscriminator: "triangle")]
[JsonDerivedType(typeof(AnotherSquare), typeDiscriminator: "square")]
internal abstract class AnotherShape
{
public required string ShapeType { get; set; }
public string Color { get; set; } = string.Empty;
public int Sides { get; set; }
}
internal class AnotherTriangle : AnotherShape
{
public double Hypotenuse { get; set; }
}
internal class AnotherSquare : AnotherShape
{
public double Area { get; set; }
}
// key.Type == AnotherShape
JsonSchemaExporter.GetJsonSchemaAsNode(_jsonSerializerOptions, key.Type); // throws here
I think the issue might be happening when the schema generator inserts the discriminator property into a child schema. The modifications that we make don't touch the child schema.
although I couldn't reproduce the error in the standalone JsonSchemaMapper component.
What did your repro look like?
I used the repro provided here but with JsonSchemaMapper
instead of JsonSchemaExporter
. Could you please transfer the issue back to runtime if it repros for JsonSchemaExporter
?
OK -- I'll send this back to the runtime repo. The repro here uses JsonSchemaExporter
.
I still wasn't able to reproduce the issue as-is, but it did occur once I changed the type discriminator property name so that it matches the casing of the ShapeType
property. In that case however the type discriminator property name conflicts with a property name, so the type is configured incorrectly and the generated schema would be ambiguous.
Just to confirm that I'm looking at the same manifestation of the problem, how is the _jsonSerializerOptions
in the repro being configured?
It's resolved from ASP.NET Core's JsonOptions service in DI. The default configuration for it is here.
I still can't repro. Adapting from ASP.NET Core defaults here's what I got:
[Fact]
public void Repro()
{
JsonSerializerOptions options = new()
{
TypeInfoResolver = new DefaultJsonTypeInfoResolver(),
Encoder = Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
JsonNode schema = options.GetJsonSchemaAsNode(typeof(Shape));
}
[JsonPolymorphic(TypeDiscriminatorPropertyName = "shapeType")]
[JsonDerivedType(typeof(Triangle), typeDiscriminator: "triangle")]
[JsonDerivedType(typeof(Square), typeDiscriminator: "square")]
[JsonDerivedType(typeof(Circle), typeDiscriminator: "circle")]
public abstract class Shape
{
public string ShapeType { get; set; }
public string Color { get; set; } = "";
public int Sides { get; set; }
}
public class Triangle : Shape
{
public double Hypotenuse { get; set; }
}
public class Square : Shape
{
public double Area { get; set; }
}
public class Circle : Shape
{
public double Radius { get; set; }
}
@eiriktsarpalis Thanks for trying this out. I suppose there's something missing between the minimal repro and the repro with our JSON serializer options. I'll transfer this back to us and take another look.
Description
Build for a project that uses the JsonPolymorphic attribute with TypeDiscriminatorPropertyName throws an exception if 1) the project is configured to generate an OpenAPI document at build time, and b) the discriminator property is already declared in the class.
Note that a similar project in .NET 8 builds cleanly.
Reproduction Steps
I have created a minimal repro for this problem in a branch in my aspnet-openapi-examples project.
https://github.com/mikekistler/aspnet-openapi-examples/tree/bug-104064
The branch has a series of commits that illustrate that a) the project builds cleanly on .NET 8, and b) the exception comes after the final commit which adds the .NET 9 feature for generating OpenAPI documents.
The exception message indicates that the crash occurs when attempting to a field that already exists. Most likely this is attempting to add the discriminator field.
Expected behavior
Rather than crash, I think logic should simply bypass adding the discriminator field if it is already present in the class, as seems to be the behavior in .NET 8.
Actual behavior
Here's the full stack trace for the exception:
Regression?
While technically not a regression, I think some might view it that way because the application code causing the crash is unchanged from the .NET 8 version that builds cleanly.
Known Workarounds
The workaround seems to be removing the
ShapeType
property from the class and removing any references to it -- such as setting it to specific values -- elsewhere in the code.Configuration
dotnet --version: 9.0.100-preview.6.24320.9 OS and version: Windows 11 Architecture: x64 (dev box)
Other information
No response