Skip to content

Commit 7f5ce1e

Browse files
Add JsonSchemaExporterContext.ParentTypeInfo (#104550)
1 parent 0dd2a62 commit 7f5ce1e

File tree

4 files changed

+51
-7
lines changed

4 files changed

+51
-7
lines changed

src/libraries/System.Text.Json/ref/System.Text.Json.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,7 @@ public readonly partial struct JsonSchemaExporterContext
914914
{
915915
private readonly object _dummy;
916916
private readonly int _dummyPrimitive;
917+
public System.Text.Json.Serialization.Metadata.JsonTypeInfo? BaseTypeInfo { get { throw null; } }
917918
public System.Text.Json.Serialization.Metadata.JsonPropertyInfo? PropertyInfo { get { throw null; } }
918919
public System.ReadOnlySpan<string> Path { get { throw null; } }
919920
public System.Text.Json.Serialization.Metadata.JsonTypeInfo TypeInfo { get { throw null; } }

src/libraries/System.Text.Json/src/System/Text/Json/Schema/JsonSchemaExporter.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ private static JsonSchema MapJsonSchemaCore(
6868
JsonPropertyInfo? propertyInfo = null,
6969
JsonConverter? customConverter = null,
7070
JsonNumberHandling? customNumberHandling = null,
71-
Type? parentPolymorphicType = null,
71+
JsonTypeInfo? parentPolymorphicTypeInfo = null,
7272
bool parentPolymorphicTypeContainsTypesWithoutDiscriminator = false,
7373
bool parentPolymorphicTypeIsNonNullable = false,
7474
KeyValuePair<string, JsonSchema>? typeDiscriminator = null,
@@ -90,7 +90,7 @@ private static JsonSchema MapJsonSchemaCore(
9090
return CompleteSchema(ref state, schema);
9191
}
9292

93-
if (parentPolymorphicType is null && typeInfo.PolymorphismOptions is { DerivedTypes.Count: > 0 } polyOptions)
93+
if (parentPolymorphicTypeInfo is null && typeInfo.PolymorphismOptions is { DerivedTypes.Count: > 0 } polyOptions)
9494
{
9595
// This is the base type of a polymorphic type hierarchy. The schema for this type
9696
// will include an "anyOf" property with the schemas for all derived types.
@@ -133,7 +133,7 @@ private static JsonSchema MapJsonSchemaCore(
133133
JsonSchema derivedSchema = MapJsonSchemaCore(
134134
ref state,
135135
derivedTypeInfo,
136-
parentPolymorphicType: typeInfo.Type,
136+
parentPolymorphicTypeInfo: typeInfo,
137137
typeDiscriminator: derivedTypeDiscriminator,
138138
parentPolymorphicTypeContainsTypesWithoutDiscriminator: containsTypesWithoutDiscriminator,
139139
parentPolymorphicTypeIsNonNullable: propertyInfo is { IsGetNullable: false, IsSetNullable: false },
@@ -372,7 +372,7 @@ JsonSchema CompleteSchema(ref GenerationState state, JsonSchema schema)
372372
if (state.ExporterOptions.TransformSchemaNode != null)
373373
{
374374
// Prime the schema for invocation by the JsonNode transformer.
375-
schema.ExporterContext = state.CreateContext(typeInfo, propertyInfo);
375+
schema.ExporterContext = state.CreateContext(typeInfo, propertyInfo, parentPolymorphicTypeInfo);
376376
}
377377

378378
return schema;
@@ -454,9 +454,9 @@ public void PopGeneratedType()
454454
_generationStack.RemoveAt(_generationStack.Count - 1);
455455
}
456456

457-
public JsonSchemaExporterContext CreateContext(JsonTypeInfo typeInfo, JsonPropertyInfo? propertyInfo)
457+
public JsonSchemaExporterContext CreateContext(JsonTypeInfo typeInfo, JsonPropertyInfo? propertyInfo, JsonTypeInfo? baseTypeInfo)
458458
{
459-
return new JsonSchemaExporterContext(typeInfo, propertyInfo, _currentPath.ToArray());
459+
return new JsonSchemaExporterContext(typeInfo, propertyInfo, baseTypeInfo, _currentPath.ToArray());
460460
}
461461

462462
private static string FormatJsonPointer(List<string> currentPathList, int depth)

src/libraries/System.Text.Json/src/System/Text/Json/Schema/JsonSchemaExporterContext.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,15 @@ public readonly struct JsonSchemaExporterContext
1212
{
1313
private readonly string[] _path;
1414

15-
internal JsonSchemaExporterContext(JsonTypeInfo typeInfo, JsonPropertyInfo? propertyInfo, string[] path)
15+
internal JsonSchemaExporterContext(
16+
JsonTypeInfo typeInfo,
17+
JsonPropertyInfo? propertyInfo,
18+
JsonTypeInfo? baseTypeInfo,
19+
string[] path)
1620
{
1721
TypeInfo = typeInfo;
1822
PropertyInfo = propertyInfo;
23+
BaseTypeInfo = baseTypeInfo;
1924
_path = path;
2025
}
2126

@@ -29,6 +34,11 @@ internal JsonSchemaExporterContext(JsonTypeInfo typeInfo, JsonPropertyInfo? prop
2934
/// </summary>
3035
public JsonPropertyInfo? PropertyInfo { get; }
3136

37+
/// <summary>
38+
/// Gets the <see cref="JsonTypeInfo"/> for polymorphic base type if the schema is being generated for a derived type.
39+
/// </summary>
40+
public JsonTypeInfo? BaseTypeInfo { get; }
41+
3242
/// <summary>
3343
/// The path to the current node in the generated JSON schema.
3444
/// </summary>

src/libraries/System.Text.Json/tests/Common/JsonSchemaExporterTests.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,39 @@ public void JsonSerializerOptions_SmallMaxDepth_ThrowsInvalidOperationException(
112112
Assert.Contains("depth", ex.Message);
113113
}
114114

115+
[Theory]
116+
[InlineData(typeof(int))]
117+
[InlineData(typeof(string))]
118+
[InlineData(typeof(SimplePoco))]
119+
[InlineData(typeof(DiscriminatedUnion))]
120+
public void JsonSchemaExporterContext_BaseTypeInfo_ReturnsExpectedValue(Type type)
121+
{
122+
bool isCallbackInvoked = false;
123+
JsonSerializerOptions options = Serializer.DefaultOptions;
124+
JsonSchemaExporterOptions exporterOptions = new()
125+
{
126+
TransformSchemaNode = (ctx, node) =>
127+
{
128+
if (typeof(DiscriminatedUnion).IsAssignableFrom(ctx.TypeInfo.Type) &&
129+
typeof(DiscriminatedUnion) != ctx.TypeInfo.Type)
130+
{
131+
Assert.NotNull(ctx.BaseTypeInfo);
132+
Assert.Equal(typeof(DiscriminatedUnion), ctx.BaseTypeInfo.Type);
133+
}
134+
else
135+
{
136+
Assert.Null(ctx.BaseTypeInfo);
137+
}
138+
139+
isCallbackInvoked = true;
140+
return node;
141+
}
142+
};
143+
144+
options.GetJsonSchemaAsNode(type, exporterOptions);
145+
Assert.True(isCallbackInvoked);
146+
}
147+
115148
[Fact]
116149
public void ReferenceHandlePreserve_Enabled_ThrowsNotSupportedException()
117150
{

0 commit comments

Comments
 (0)