From 874217eac201422290b9234eddb466821caa3344 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 27 Jul 2026 10:16:06 +0000 Subject: [PATCH] Backport PR #130881: Add contentEncoding: base64 to JSON schema for byte[], Memory, and ReadOnlyMemory Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com> --- .../src/System/Text/Json/Schema/JsonSchema.cs | 9 +++++++++ .../Serialization/Converters/Value/ByteArrayConverter.cs | 2 +- .../Converters/Value/MemoryByteConverter.cs | 2 +- .../Converters/Value/ReadOnlyMemoryByteConverter.cs | 2 +- .../tests/Common/JsonSchemaExporterTests.TestTypes.cs | 6 +++--- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Schema/JsonSchema.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Schema/JsonSchema.cs index 64bf0729e69037..bde68b7f31c769 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Schema/JsonSchema.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Schema/JsonSchema.cs @@ -23,6 +23,7 @@ internal sealed class JsonSchema internal const string AnyOfPropertyName = "anyOf"; internal const string ConstPropertyName = "const"; internal const string DefaultPropertyName = "default"; + internal const string ContentEncodingPropertyName = "contentEncoding"; internal const string MinLengthPropertyName = "minLength"; internal const string MaxLengthPropertyName = "maxLength"; internal const string DeprecatedPropertyName = "deprecated"; @@ -81,6 +82,8 @@ public JsonSchema() { } public bool? Deprecated { get; set { VerifyMutable(); field = value; } } + public string? ContentEncoding { get; set { VerifyMutable(); field = value; } } + public JsonSchemaExporterContext? ExporterContext { get; set; } public int KeywordCount @@ -111,6 +114,7 @@ public int KeywordCount Count(MinLength is not null); Count(MaxLength is not null); Count(Deprecated is not null); + Count(ContentEncoding is not null); return count; @@ -247,6 +251,11 @@ public JsonNode ToJsonNode(JsonSchemaExporterOptions options) objSchema.Add(DeprecatedPropertyName, (JsonNode)deprecated); } + if (ContentEncoding is not null) + { + objSchema.Add(ContentEncodingPropertyName, ContentEncoding); + } + return CompleteSchema(objSchema); JsonNode CompleteSchema(JsonNode schema) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ByteArrayConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ByteArrayConverter.cs index 7da350f9528a39..2b97f7db3f0839 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ByteArrayConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ByteArrayConverter.cs @@ -29,7 +29,7 @@ public override void Write(Utf8JsonWriter writer, byte[]? value, JsonSerializerO } } - internal override JsonSchema? GetSchema(JsonNumberHandling _) => new() { Type = JsonSchemaType.String }; + internal override JsonSchema? GetSchema(JsonNumberHandling _) => new() { Type = JsonSchemaType.String, ContentEncoding = "base64" }; internal override JsonValueType GetSupportedJsonValueTypes(JsonNumberHandling _) => JsonValueType.String; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/MemoryByteConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/MemoryByteConverter.cs index eedb6f129708d5..f400e147e9b5af 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/MemoryByteConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/MemoryByteConverter.cs @@ -20,7 +20,7 @@ public override void Write(Utf8JsonWriter writer, Memory value, JsonSerial writer.WriteBase64StringValue(value.Span); } - internal override JsonSchema? GetSchema(JsonNumberHandling _) => new() { Type = JsonSchemaType.String }; + internal override JsonSchema? GetSchema(JsonNumberHandling _) => new() { Type = JsonSchemaType.String, ContentEncoding = "base64" }; internal override JsonValueType GetSupportedJsonValueTypes(JsonNumberHandling _) => JsonValueType.String; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ReadOnlyMemoryByteConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ReadOnlyMemoryByteConverter.cs index 59aade6c5c24c1..412b865703f77c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ReadOnlyMemoryByteConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ReadOnlyMemoryByteConverter.cs @@ -20,7 +20,7 @@ public override void Write(Utf8JsonWriter writer, ReadOnlyMemory value, Js writer.WriteBase64StringValue(value.Span); } - internal override JsonSchema? GetSchema(JsonNumberHandling _) => new() { Type = JsonSchemaType.String }; + internal override JsonSchema? GetSchema(JsonNumberHandling _) => new() { Type = JsonSchemaType.String, ContentEncoding = "base64" }; internal override JsonValueType GetSupportedJsonValueTypes(JsonNumberHandling _) => JsonValueType.String; } diff --git a/src/libraries/System.Text.Json/tests/Common/JsonSchemaExporterTests.TestTypes.cs b/src/libraries/System.Text.Json/tests/Common/JsonSchemaExporterTests.TestTypes.cs index 18037517183e95..a03b3a6dabbb27 100644 --- a/src/libraries/System.Text.Json/tests/Common/JsonSchemaExporterTests.TestTypes.cs +++ b/src/libraries/System.Text.Json/tests/Common/JsonSchemaExporterTests.TestTypes.cs @@ -57,10 +57,10 @@ public static IEnumerable GetTestDataCore() yield return new TestData( Value: [1, 2, 3], AdditionalValues: [[]], - ExpectedJsonSchema: """{"type":["string","null"]}"""); + ExpectedJsonSchema: """{"type":["string","null"],"contentEncoding":"base64"}"""); - yield return new TestData>(new byte[] { 1, 2, 3 }, ExpectedJsonSchema: """{"type":"string"}"""); - yield return new TestData>(new byte[] { 1, 2, 3 }, ExpectedJsonSchema: """{"type":"string"}"""); + yield return new TestData>(new byte[] { 1, 2, 3 }, ExpectedJsonSchema: """{"type":"string","contentEncoding":"base64"}"""); + yield return new TestData>(new byte[] { 1, 2, 3 }, ExpectedJsonSchema: """{"type":"string","contentEncoding":"base64"}"""); yield return new TestData( Value: new(2024, 06, 06, 21, 39, 42, DateTimeKind.Utc), ExpectedJsonSchema: """{"type":"string","format":"date-time"}""");