diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.cs index 1eec8124a3976f..24c19d8c55c108 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -157,10 +157,10 @@ public abstract partial class JsonNamingPolicy { protected JsonNamingPolicy() { } public static System.Text.Json.JsonNamingPolicy CamelCase { get { throw null; } } - public static System.Text.Json.JsonNamingPolicy SnakeCaseLower { get { throw null; } } - public static System.Text.Json.JsonNamingPolicy SnakeCaseUpper { get { throw null; } } public static System.Text.Json.JsonNamingPolicy KebabCaseLower { get { throw null; } } public static System.Text.Json.JsonNamingPolicy KebabCaseUpper { get { throw null; } } + public static System.Text.Json.JsonNamingPolicy SnakeCaseLower { get { throw null; } } + public static System.Text.Json.JsonNamingPolicy SnakeCaseUpper { get { throw null; } } public abstract string ConvertName(string name); } public readonly partial struct JsonProperty @@ -191,42 +191,55 @@ public partial struct JsonReaderState } public static partial class JsonSerializer { + public static object? Deserialize(System.IO.Stream utf8Json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static object? Deserialize(System.IO.Stream utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static object? Deserialize(System.IO.Stream utf8Json, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context) { throw null; } + public static object? Deserialize(System.ReadOnlySpan utf8Json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static object? Deserialize(System.ReadOnlySpan utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static object? Deserialize(System.ReadOnlySpan utf8Json, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context) { throw null; } + public static object? Deserialize([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("Json")] System.ReadOnlySpan json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static object? Deserialize([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("Json")] System.ReadOnlySpan json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static object? Deserialize([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("Json")] System.ReadOnlySpan json, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context) { throw null; } + public static object? Deserialize([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("Json")] string json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static object? Deserialize([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("Json")] string json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static object? Deserialize([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("Json")] string json, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context) { throw null; } + public static object? Deserialize(this System.Text.Json.JsonDocument document, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static object? Deserialize(this System.Text.Json.JsonDocument document, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static object? Deserialize(this System.Text.Json.JsonDocument document, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context) { throw null; } + public static object? Deserialize(this System.Text.Json.JsonElement element, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static object? Deserialize(this System.Text.Json.JsonElement element, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static object? Deserialize(this System.Text.Json.JsonElement element, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context) { throw null; } + public static object? Deserialize(this System.Text.Json.Nodes.JsonNode? node, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static object? Deserialize(this System.Text.Json.Nodes.JsonNode? node, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static object? Deserialize(this System.Text.Json.Nodes.JsonNode? node, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context) { throw null; } + public static object? Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static object? Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static object? Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context) { throw null; } + public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Collections.Generic.IAsyncEnumerable DeserializeAsyncEnumerable(System.IO.Stream utf8Json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] + public static System.Collections.Generic.IAsyncEnumerable DeserializeAsyncEnumerable(System.IO.Stream utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Collections.Generic.IAsyncEnumerable DeserializeAsyncEnumerable(System.IO.Stream utf8Json, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } @@ -267,18 +280,22 @@ public static partial class JsonSerializer [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static TValue? Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static TValue? Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } + public static void Serialize(System.IO.Stream utf8Json, object? value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static void Serialize(System.IO.Stream utf8Json, object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { } public static void Serialize(System.IO.Stream utf8Json, object? value, System.Type inputType, System.Text.Json.Serialization.JsonSerializerContext context) { } + public static string Serialize(object? value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static string Serialize(object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static string Serialize(object? value, System.Type inputType, System.Text.Json.Serialization.JsonSerializerContext context) { throw null; } + public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { } public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? value, System.Type inputType, System.Text.Json.Serialization.JsonSerializerContext context) { } + public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object? value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } @@ -287,6 +304,7 @@ public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? val [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, TValue value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Text.Json.JsonDocument SerializeToDocument(object? value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Text.Json.JsonDocument SerializeToDocument(object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } @@ -295,6 +313,7 @@ public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? val [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Text.Json.JsonDocument SerializeToDocument(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static System.Text.Json.JsonDocument SerializeToDocument(TValue value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } + public static System.Text.Json.JsonElement SerializeToElement(object? value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Text.Json.JsonElement SerializeToElement(object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } @@ -303,6 +322,7 @@ public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? val [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Text.Json.JsonElement SerializeToElement(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static System.Text.Json.JsonElement SerializeToElement(TValue value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } + public static System.Text.Json.Nodes.JsonNode? SerializeToNode(object? value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Text.Json.Nodes.JsonNode? SerializeToNode(object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } @@ -311,6 +331,7 @@ public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? val [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Text.Json.Nodes.JsonNode? SerializeToNode(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static System.Text.Json.Nodes.JsonNode? SerializeToNode(TValue value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } + public static byte[] SerializeToUtf8Bytes(object? value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static byte[] SerializeToUtf8Bytes(object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } @@ -957,7 +978,7 @@ public sealed partial class JsonPropertyOrderAttribute : System.Text.Json.Serial public JsonPropertyOrderAttribute(int order) { } public int Order { get { throw null; } } } - [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple = false)] + [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple=false)] public sealed partial class JsonRequiredAttribute : System.Text.Json.Serialization.JsonAttribute { public JsonRequiredAttribute() { } @@ -1205,7 +1226,6 @@ internal JsonTypeInfo() { } public System.Func? CreateObject { get { throw null; } set { } } public bool IsReadOnly { get { throw null; } } public System.Text.Json.Serialization.Metadata.JsonTypeInfoKind Kind { get { throw null; } } - public void MakeReadOnly() { throw null; } public System.Text.Json.Serialization.JsonNumberHandling? NumberHandling { get { throw null; } set { } } public System.Action? OnDeserialized { get { throw null; } set { } } public System.Action? OnDeserializing { get { throw null; } set { } } @@ -1224,6 +1244,7 @@ internal JsonTypeInfo() { } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")] public static System.Text.Json.Serialization.Metadata.JsonTypeInfo CreateJsonTypeInfo(System.Text.Json.JsonSerializerOptions options) { throw null; } + public void MakeReadOnly() { } } public enum JsonTypeInfoKind { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Document.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Document.cs index 74361b7a17294e..5d47b54b022177 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Document.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Document.cs @@ -92,10 +92,6 @@ public static partial class JsonSerializer /// /// is not compatible with the JSON. /// - /// - /// There is no compatible - /// for or its serializable members. - /// public static TValue? Deserialize(this JsonDocument document, JsonTypeInfo jsonTypeInfo) { if (document is null) @@ -112,6 +108,34 @@ public static partial class JsonSerializer return ReadFromSpan(utf8Json, jsonTypeInfo); } + /// + /// Converts the representing a single JSON value into an instance specified by the . + /// + /// The to convert. + /// Metadata about the type to convert. + /// + /// is . + /// + /// -or- + /// + /// is . + /// + public static object? Deserialize(this JsonDocument document, JsonTypeInfo jsonTypeInfo) + { + if (document is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(document)); + } + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + ReadOnlySpan utf8Json = document.GetRootRawValue().Span; + return ReadFromSpanAsObject(utf8Json, jsonTypeInfo); + } + /// /// Converts the representing a single JSON value into a . /// diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Element.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Element.cs index ffa12ec7ac5d76..301979e50b43b0 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Element.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Element.cs @@ -92,6 +92,27 @@ public static partial class JsonSerializer return ReadFromSpan(utf8Json, jsonTypeInfo); } + /// + /// Converts the representing a single JSON value into an instance specified by the . + /// + /// A representation of the JSON value. + /// The to convert. + /// Metadata about the type to convert. + /// + /// is . + /// + public static object? Deserialize(this JsonElement element, JsonTypeInfo jsonTypeInfo) + { + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + ReadOnlySpan utf8Json = element.GetRawValue().Span; + return ReadFromSpanAsObject(utf8Json, jsonTypeInfo); + } + /// /// Converts the representing a single JSON value into a . /// diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Node.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Node.cs index 562faa69c07f1a..b22be1ceec6762 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Node.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Node.cs @@ -73,10 +73,6 @@ public static partial class JsonSerializer /// /// is not compatible with the JSON. /// - /// - /// There is no compatible - /// for or its serializable members. - /// public static TValue? Deserialize(this JsonNode? node, JsonTypeInfo jsonTypeInfo) { if (jsonTypeInfo is null) @@ -88,6 +84,26 @@ public static partial class JsonSerializer return ReadFromNode(node, jsonTypeInfo); } + /// + /// Converts the representing a single JSON value into an instance specified by the . + /// + /// A representation of the JSON value. + /// The to convert. + /// Metadata about the type to convert. + /// + /// is . + /// + public static object? Deserialize(this JsonNode? node, JsonTypeInfo jsonTypeInfo) + { + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + return ReadFromNodeAsObject(node, jsonTypeInfo); + } + /// /// Converts the representing a single JSON value into a . /// diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Span.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Span.cs index 673913e71c5e3b..7a9a2bc028acb5 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Span.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Span.cs @@ -76,11 +76,7 @@ public static partial class JsonSerializer /// /// The JSON is invalid, /// is not compatible with the JSON, - /// or when there is remaining data in the Stream. - /// - /// - /// There is no compatible - /// for or its serializable members. + /// or when there is remaining data in the buffer. /// public static TValue? Deserialize(ReadOnlySpan utf8Json, JsonTypeInfo jsonTypeInfo) { @@ -93,6 +89,27 @@ public static partial class JsonSerializer return ReadFromSpan(utf8Json, jsonTypeInfo); } + /// + /// Parses the UTF-8 encoded text representing a single JSON value into an instance specified by the . + /// + /// A representation of the JSON value. + /// JSON text to parse. + /// Metadata about the type to convert. + /// + /// The JSON is invalid, + /// or there is remaining data in the buffer. + /// + public static object? Deserialize(ReadOnlySpan utf8Json, JsonTypeInfo jsonTypeInfo) + { + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + return ReadFromSpanAsObject(utf8Json, jsonTypeInfo); + } + /// /// Parses the UTF-8 encoded text representing a single JSON value into a . /// diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs index de0dd0a0785705..4902e9afc2939d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs @@ -2,12 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; -using System.Runtime.CompilerServices; using System.Text.Json.Serialization; -using System.Text.Json.Serialization.Converters; using System.Text.Json.Serialization.Metadata; using System.Threading; using System.Threading.Tasks; @@ -193,10 +190,6 @@ public static partial class JsonSerializer /// is not compatible with the JSON, /// or when there is remaining data in the Stream. /// - /// - /// There is no compatible - /// for or its serializable members. - /// public static ValueTask DeserializeAsync( Stream utf8Json, JsonTypeInfo jsonTypeInfo, @@ -215,6 +208,41 @@ public static partial class JsonSerializer return jsonTypeInfo.DeserializeAsync(utf8Json, cancellationToken); } + /// + /// Reads the UTF-8 encoded text representing a single JSON value into an instance specified by the . + /// The Stream will be read to completion. + /// + /// A representation of the JSON value. + /// JSON data to parse. + /// Metadata about the type to convert. + /// + /// The that can be used to cancel the read operation. + /// + /// + /// or is . + /// + /// + /// The JSON is invalid, + /// or when there is remaining data in the Stream. + /// + public static ValueTask DeserializeAsync( + Stream utf8Json, + JsonTypeInfo jsonTypeInfo, + CancellationToken cancellationToken = default) + { + if (utf8Json is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(utf8Json)); + } + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + return jsonTypeInfo.DeserializeAsObjectAsync(utf8Json, cancellationToken); + } + /// /// Reads the UTF-8 encoded text representing a single JSON value into a . /// The Stream will be read to completion. @@ -231,10 +259,6 @@ public static partial class JsonSerializer /// is not compatible with the JSON, /// or when there is remaining data in the Stream. /// - /// - /// There is no compatible - /// for or its serializable members. - /// public static TValue? Deserialize( Stream utf8Json, JsonTypeInfo jsonTypeInfo) @@ -252,6 +276,37 @@ public static partial class JsonSerializer return jsonTypeInfo.Deserialize(utf8Json); } + /// + /// Reads the UTF-8 encoded text representing a single JSON value into an instance specified by the . + /// The Stream will be read to completion. + /// + /// A representation of the JSON value. + /// JSON data to parse. + /// Metadata about the type to convert. + /// + /// or is . + /// + /// + /// The JSON is invalid, + /// or when there is remaining data in the Stream. + /// + public static object? Deserialize( + Stream utf8Json, + JsonTypeInfo jsonTypeInfo) + { + if (utf8Json is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(utf8Json)); + } + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + return jsonTypeInfo.DeserializeAsObject(utf8Json); + } + /// /// Reads the UTF-8 encoded text representing a single JSON value into a . /// The Stream will be read to completion. @@ -357,7 +412,6 @@ public static partial class JsonSerializer /// JSON data to parse. /// Options to control the behavior during reading. /// The that can be used to cancel the read operation. - /// An representation of the JSON value. /// /// is . /// @@ -386,7 +440,6 @@ public static partial class JsonSerializer /// JSON data to parse. /// Metadata about the element type to convert. /// The that can be used to cancel the read operation. - /// An representation of the JSON value. /// /// or is . /// @@ -408,5 +461,63 @@ public static partial class JsonSerializer jsonTypeInfo.EnsureConfigured(); return jsonTypeInfo.DeserializeAsyncEnumerable(utf8Json, cancellationToken); } + + /// + /// Wraps the UTF-8 encoded text into an + /// that can be used to deserialize root-level JSON arrays in a streaming manner. + /// + /// An representation of the provided JSON array. + /// JSON data to parse. + /// The type of the object to convert to and return. + /// Options to control the behavior during reading. + /// The that can be used to cancel the read operation. + /// + /// or is . + /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] + [RequiresDynamicCode(SerializationRequiresDynamicCodeMessage)] + public static IAsyncEnumerable DeserializeAsyncEnumerable( + Stream utf8Json, + Type returnType, + JsonSerializerOptions? options = null, + CancellationToken cancellationToken = default) + { + if (utf8Json is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(utf8Json)); + } + + JsonTypeInfo jsonTypeInfo = GetTypeInfo(options, returnType); + return jsonTypeInfo.DeserializeAsyncEnumerableAsObject(utf8Json, cancellationToken); + } + + /// + /// Wraps the UTF-8 encoded text into an + /// that can be used to deserialize root-level JSON arrays in a streaming manner. + /// + /// An representation of the provided JSON array. + /// JSON data to parse. + /// Metadata about the element type to convert. + /// The that can be used to cancel the read operation. + /// + /// or is . + /// + public static IAsyncEnumerable DeserializeAsyncEnumerable( + Stream utf8Json, + JsonTypeInfo jsonTypeInfo, + CancellationToken cancellationToken = default) + { + if (utf8Json is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(utf8Json)); + } + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + return jsonTypeInfo.DeserializeAsyncEnumerableAsObject(utf8Json, cancellationToken); + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs index b8772db69421e2..e359799097e91e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs @@ -197,10 +197,6 @@ public static partial class JsonSerializer /// -or- /// /// There is remaining data in the string beyond a single JSON value. - /// - /// There is no compatible - /// for or its serializable members. - /// /// Using a is not as efficient as using the /// UTF-8 methods since the implementation natively uses UTF-8. /// @@ -243,10 +239,6 @@ public static partial class JsonSerializer /// -or- /// /// There is remaining data in the string beyond a single JSON value. - /// - /// There is no compatible - /// for or its serializable members. - /// /// Using a is not as efficient as using the /// UTF-8 methods since the implementation natively uses UTF-8. /// @@ -261,6 +253,72 @@ public static partial class JsonSerializer return ReadFromSpan(json, jsonTypeInfo); } + /// + /// Parses the text representing a single JSON value into an instance specified by the . + /// + /// A representation of the JSON value. + /// JSON text to parse. + /// Metadata about the type to convert. + /// + /// is . + /// + /// -or- + /// + /// is . + /// + /// + /// The JSON is invalid. + /// + /// -or- + /// + /// There is remaining data in the string beyond a single JSON value. + /// Using a is not as efficient as using the + /// UTF-8 methods since the implementation natively uses UTF-8. + /// + public static object? Deserialize([StringSyntax(StringSyntaxAttribute.Json)] string json, JsonTypeInfo jsonTypeInfo) + { + if (json is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(json)); + } + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + return ReadFromSpanAsObject(json.AsSpan(), jsonTypeInfo); + } + + /// + /// Parses the text representing a single JSON value into an instance specified by the . + /// + /// A representation of the JSON value. + /// JSON text to parse. + /// Metadata about the type to convert. + /// + /// is . + /// + /// + /// The JSON is invalid. + /// + /// -or- + /// + /// There is remaining data in the string beyond a single JSON value. + /// Using a is not as efficient as using the + /// UTF-8 methods since the implementation natively uses UTF-8. + /// + public static object? Deserialize([StringSyntax(StringSyntaxAttribute.Json)] ReadOnlySpan json, JsonTypeInfo jsonTypeInfo) + { + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + return ReadFromSpanAsObject(json, jsonTypeInfo); + } + /// /// Parses the text representing a single JSON value into a . /// diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs index 4416cc2448474d..fd424c0606cb81 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs @@ -135,10 +135,6 @@ public static partial class JsonSerializer /// /// is using unsupported options. /// - /// - /// There is no compatible - /// for or its serializable members. - /// /// /// /// If the property of @@ -171,7 +167,56 @@ public static partial class JsonSerializer } jsonTypeInfo.EnsureConfigured(); - return Read(ref reader, jsonTypeInfo); + return Read(ref reader, jsonTypeInfo); + } + + /// + /// Reads one JSON value (including objects or arrays) from the provided reader into an instance specified by the . + /// + /// A representation of the JSON value. + /// The reader to read. + /// Metadata about the type to convert. + /// + /// The JSON is invalid, + /// is not compatible with the JSON, + /// or a value could not be read from the reader. + /// + /// + /// is using unsupported options. + /// + /// + /// + /// If the property of + /// is or , the + /// reader will be advanced by one call to to determine + /// the start of the value. + /// + /// + /// + /// Upon completion of this method, will be positioned at the + /// final token in the JSON value. If an exception is thrown, the reader is reset to + /// the state it was in when the method was called. + /// + /// + /// + /// This method makes a copy of the data the reader acted on, so there is no caller + /// requirement to maintain data integrity beyond the return of this method. + /// + /// + /// + /// The used to create the instance of the take precedence over the when they conflict. + /// Hence, , , and are used while reading. + /// + /// + public static object? Deserialize(ref Utf8JsonReader reader, JsonTypeInfo jsonTypeInfo) + { + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + return ReadAsObject(ref reader, jsonTypeInfo); } /// diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.ByteArray.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.ByteArray.cs index 5d336a4879fd7a..bc13797f4231f0 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.ByteArray.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.ByteArray.cs @@ -65,10 +65,6 @@ public static byte[] SerializeToUtf8Bytes( /// A UTF-8 representation of the value. /// The value to convert. /// Metadata about the type to convert. - /// - /// There is no compatible - /// for or its serializable members. - /// /// /// is . /// @@ -83,6 +79,29 @@ public static byte[] SerializeToUtf8Bytes(TValue value, JsonTypeInfo + /// Converts the provided value into a array. + /// + /// A UTF-8 representation of the value. + /// The value to convert. + /// Metadata about the type to convert. + /// + /// is . + /// + /// + /// does not match the type of . + /// + public static byte[] SerializeToUtf8Bytes(object? value, JsonTypeInfo jsonTypeInfo) + { + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + return WriteBytesAsObject(value, jsonTypeInfo); + } + /// /// Converts the provided value into a array. /// diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Document.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Document.cs index 644bd0d4325009..f12459b71b65bb 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Document.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Document.cs @@ -62,10 +62,6 @@ public static JsonDocument SerializeToDocument(object? value, Type inputType, Js /// A representation of the value. /// The value to convert. /// Metadata about the type to convert. - /// - /// There is no compatible - /// for or its serializable members. - /// /// /// is . /// @@ -80,6 +76,29 @@ public static JsonDocument SerializeToDocument(TValue value, JsonTypeInf return WriteDocument(value, jsonTypeInfo); } + /// + /// Converts the provided value into a . + /// + /// A representation of the value. + /// The value to convert. + /// Metadata about the type to convert. + /// + /// is . + /// + /// + /// does not match the type of . + /// + public static JsonDocument SerializeToDocument(object? value, JsonTypeInfo jsonTypeInfo) + { + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + return WriteDocumentAsObject(value, jsonTypeInfo); + } + /// /// Converts the provided value into a . /// diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Element.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Element.cs index 1fdad1abf6e7cb..90302e81cbc2e4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Element.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Element.cs @@ -62,10 +62,6 @@ public static JsonElement SerializeToElement(object? value, Type inputType, Json /// A representation of the value. /// The value to convert. /// Metadata about the type to convert. - /// - /// There is no compatible - /// for or its serializable members. - /// /// /// is . /// @@ -80,6 +76,29 @@ public static JsonElement SerializeToElement(TValue value, JsonTypeInfo< return WriteElement(value, jsonTypeInfo); } + /// + /// Converts the provided value into a . + /// + /// A representation of the value. + /// The value to convert. + /// Metadata about the type to convert. + /// + /// is . + /// + /// + /// does not match the type of . + /// + public static JsonElement SerializeToElement(object? value, JsonTypeInfo jsonTypeInfo) + { + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + return WriteElementAsObject(value, jsonTypeInfo); + } + /// /// Converts the provided value into a . /// diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Node.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Node.cs index ebb87b26c7c37d..de48a268d21187 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Node.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Node.cs @@ -63,10 +63,6 @@ public static partial class JsonSerializer /// A representation of the value. /// The value to convert. /// Metadata about the type to convert. - /// - /// There is no compatible - /// for or its serializable members. - /// /// /// is . /// @@ -81,6 +77,29 @@ public static partial class JsonSerializer return WriteNode(value, jsonTypeInfo); } + /// + /// Converts the provided value into a . + /// + /// A representation of the value. + /// The value to convert. + /// Metadata about the type to convert. + /// + /// is . + /// + /// + /// does not match the type of . + /// + public static JsonNode? SerializeToNode(object? value, JsonTypeInfo jsonTypeInfo) + { + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + return WriteNodeAsObject(value, jsonTypeInfo); + } + /// /// Converts the provided value into a . /// diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Stream.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Stream.cs index 107578964faac3..9c678e37ad3943 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Stream.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Stream.cs @@ -168,10 +168,6 @@ public static void Serialize( /// /// is . /// - /// - /// There is no compatible - /// for or its serializable members. - /// public static Task SerializeAsync( Stream utf8Json, TValue value, @@ -201,10 +197,6 @@ public static Task SerializeAsync( /// /// is . /// - /// - /// There is no compatible - /// for or its serializable members. - /// public static void Serialize( Stream utf8Json, TValue value, @@ -223,6 +215,69 @@ public static void Serialize( jsonTypeInfo.Serialize(utf8Json, value); } + /// + /// Converts the provided value to UTF-8 encoded JSON text and write it to the . + /// + /// A task that represents the asynchronous write operation. + /// The UTF-8 to write to. + /// The value to convert. + /// Metadata about the type to convert. + /// The that can be used to cancel the write operation. + /// + /// is . + /// + /// + /// does not match the type of . + /// + public static Task SerializeAsync( + Stream utf8Json, + object? value, + JsonTypeInfo jsonTypeInfo, + CancellationToken cancellationToken = default) + { + if (utf8Json is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(utf8Json)); + } + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + return jsonTypeInfo.SerializeAsObjectAsync(utf8Json, value, cancellationToken); + } + + /// + /// Converts the provided value to UTF-8 encoded JSON text and write it to the . + /// + /// The UTF-8 to write to. + /// The value to convert. + /// Metadata about the type to convert. + /// + /// is . + /// + /// + /// does not match the type of . + /// + public static void Serialize( + Stream utf8Json, + object? value, + JsonTypeInfo jsonTypeInfo) + { + if (utf8Json is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(utf8Json)); + } + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + jsonTypeInfo.SerializeAsObject(utf8Json, value); + } + /// /// Converts the provided value to UTF-8 encoded JSON text and write it to the . /// diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.String.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.String.cs index 5076cda2594da2..ed141f2d967d25 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.String.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.String.cs @@ -73,10 +73,6 @@ public static string Serialize( /// A representation of the value. /// The value to convert. /// Metadata about the type to convert. - /// - /// There is no compatible - /// for or its serializable members. - /// /// /// is . /// @@ -95,6 +91,33 @@ public static string Serialize(TValue value, JsonTypeInfo jsonTy return WriteString(value, jsonTypeInfo); } + /// + /// Converts the provided value into a . + /// + /// A representation of the value. + /// The value to convert. + /// Metadata about the type to convert. + /// + /// is . + /// + /// + /// does not match the type of . + /// + /// Using a is not as efficient as using UTF-8 + /// encoding since the implementation internally uses UTF-8. See also + /// and . + /// + public static string Serialize(object? value, JsonTypeInfo jsonTypeInfo) + { + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + return WriteStringAsObject(value, jsonTypeInfo); + } + /// /// Converts the provided value into a . /// diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Utf8JsonWriter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Utf8JsonWriter.cs index 4ccd26096fd42b..e62931f4faf61c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Utf8JsonWriter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Utf8JsonWriter.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; using System.Text.Json.Serialization.Metadata; @@ -85,10 +84,6 @@ public static void Serialize( /// /// or is . /// - /// - /// There is no compatible - /// for or its serializable members. - /// public static void Serialize(Utf8JsonWriter writer, TValue value, JsonTypeInfo jsonTypeInfo) { if (writer is null) @@ -104,6 +99,33 @@ public static void Serialize(Utf8JsonWriter writer, TValue value, JsonTy jsonTypeInfo.Serialize(writer, value); } + /// + /// Writes one JSON value (including objects or arrays) to the provided writer. + /// + /// The writer to write. + /// The value to convert and write. + /// Metadata about the type to convert. + /// + /// or is . + /// + /// + /// does not match the type of . + /// + public static void Serialize(Utf8JsonWriter writer, object? value, JsonTypeInfo jsonTypeInfo) + { + if (writer is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(writer)); + } + if (jsonTypeInfo is null) + { + ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); + } + + jsonTypeInfo.EnsureConfigured(); + jsonTypeInfo.SerializeAsObject(writer, value); + } + /// /// Writes one JSON value (including objects or arrays) to the provided writer. /// diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs index 1127853c320a8a..ecec559e43f0d5 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs @@ -774,6 +774,7 @@ private void PopulatePropertyList() internal abstract object? DeserializeAsObject(ref Utf8JsonReader reader, ref ReadStack state); internal abstract ValueTask DeserializeAsObjectAsync(Stream utf8Json, CancellationToken cancellationToken); internal abstract object? DeserializeAsObject(Stream utf8Json); + internal abstract IAsyncEnumerable DeserializeAsyncEnumerableAsObject(Stream utf8Json, CancellationToken cancellationToken); internal void CacheMember(JsonPropertyInfo jsonPropertyInfo, JsonPropertyDictionary propertyCache, ref Dictionary? ignoredMembers) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.ReadHelper.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.ReadHelper.cs index 8b5128f62bbbea..56569687fd6edb 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.ReadHelper.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfoOfT.ReadHelper.cs @@ -152,6 +152,22 @@ static async IAsyncEnumerable CreateAsyncEnumerableDeserializer( internal sealed override object? DeserializeAsObject(Stream utf8Json) => Deserialize(utf8Json); + internal sealed override IAsyncEnumerable DeserializeAsyncEnumerableAsObject(Stream utf8Json, CancellationToken cancellationToken) + { + IAsyncEnumerable typedSource = DeserializeAsyncEnumerable(utf8Json, cancellationToken); + return AsObjectEnumerable(typedSource, cancellationToken); + + static async IAsyncEnumerable AsObjectEnumerable( + IAsyncEnumerable source, + [EnumeratorCancellation] CancellationToken cancellationToken) + { + await foreach (T elem in source.WithCancellation(cancellationToken).ConfigureAwait(false)) + { + yield return elem; + } + } + } + private T? ContinueDeserialize( ref ReadBufferState bufferState, ref JsonReaderState jsonReaderState, diff --git a/src/libraries/System.Text.Json/tests/Common/JsonSerializerWrapper.cs b/src/libraries/System.Text.Json/tests/Common/JsonSerializerWrapper.cs index 8032e2fdfd6800..9435d718b0db2d 100644 --- a/src/libraries/System.Text.Json/tests/Common/JsonSerializerWrapper.cs +++ b/src/libraries/System.Text.Json/tests/Common/JsonSerializerWrapper.cs @@ -25,12 +25,16 @@ public abstract partial class JsonSerializerWrapper public abstract Task SerializeWrapper(T value, JsonTypeInfo jsonTypeInfo); + public abstract Task SerializeWrapper(object value, JsonTypeInfo jsonTypeInfo); + public abstract Task DeserializeWrapper(string json, JsonSerializerOptions options = null); public abstract Task DeserializeWrapper(string json, Type type, JsonSerializerOptions options = null); public abstract Task DeserializeWrapper(string json, JsonTypeInfo jsonTypeInfo); + public abstract Task DeserializeWrapper(string value, JsonTypeInfo jsonTypeInfo); + public abstract Task DeserializeWrapper(string json, Type type, JsonSerializerContext context); } } diff --git a/src/libraries/System.Text.Json/tests/Common/StreamingJsonSerializerWrapper.cs b/src/libraries/System.Text.Json/tests/Common/StreamingJsonSerializerWrapper.cs index ce57ceeb0e2ed6..cf09eac91336ef 100644 --- a/src/libraries/System.Text.Json/tests/Common/StreamingJsonSerializerWrapper.cs +++ b/src/libraries/System.Text.Json/tests/Common/StreamingJsonSerializerWrapper.cs @@ -22,10 +22,12 @@ public abstract partial class StreamingJsonSerializerWrapper : JsonSerializerWra public abstract Task SerializeWrapper(Stream stream, T value, JsonSerializerOptions? options = null); public abstract Task SerializeWrapper(Stream stream, object value, Type inputType, JsonSerializerContext context); public abstract Task SerializeWrapper(Stream stream, T value, JsonTypeInfo jsonTypeInfo); + public abstract Task SerializeWrapper(Stream stream, object value, JsonTypeInfo jsonTypeInfo); public abstract Task DeserializeWrapper(Stream utf8Json, Type returnType, JsonSerializerOptions? options = null); public abstract Task DeserializeWrapper(Stream utf8Json, JsonSerializerOptions? options = null); public abstract Task DeserializeWrapper(Stream utf8Json, Type returnType, JsonSerializerContext context); public abstract Task DeserializeWrapper(Stream utf8Json, JsonTypeInfo jsonTypeInfo); + public abstract Task DeserializeWrapper(Stream utf8Json, JsonTypeInfo jsonTypeInfo); public override async Task SerializeWrapper(object value, Type inputType, JsonSerializerOptions options = null) { @@ -55,6 +57,13 @@ public override async Task SerializeWrapper(T value, JsonTypeInfo return utf8Stream.AsString(); } + public override async Task SerializeWrapper(object value, JsonTypeInfo jsonTypeInfo) + { + using var utf8Stream = new Utf8MemoryStream(); + await SerializeWrapper(utf8Stream, value, jsonTypeInfo); + return utf8Stream.AsString(); + } + public override async Task DeserializeWrapper(string json, JsonSerializerOptions options = null) { using var utf8Stream = new Utf8MemoryStream(json); @@ -73,6 +82,12 @@ public override async Task DeserializeWrapper(string json, JsonTypeInfo return await DeserializeWrapper(utf8Stream, jsonTypeInfo); } + public override async Task DeserializeWrapper(string json, JsonTypeInfo jsonTypeInfo) + { + using var utf8Stream = new Utf8MemoryStream(json); + return await DeserializeWrapper(utf8Stream, jsonTypeInfo); + } + public override async Task DeserializeWrapper(string json, Type returnType, JsonSerializerContext context) { using var utf8Stream = new Utf8MemoryStream(json); diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/JsonSerializerWrapper.SourceGen.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/JsonSerializerWrapper.SourceGen.cs index 1ff38417028617..baa7377f94a163 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/JsonSerializerWrapper.SourceGen.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/JsonSerializerWrapper.SourceGen.cs @@ -46,6 +46,9 @@ public override Task SerializeWrapper(object value, Type inputType, Json public override Task SerializeWrapper(T value, JsonTypeInfo jsonTypeInfo) => throw new NotImplementedException(); + public override Task SerializeWrapper(object value, JsonTypeInfo jsonTypeInfo) + => throw new NotImplementedException(); + public override Task DeserializeWrapper(string json, JsonSerializerOptions? options = null) { JsonSerializerContext context = GetJsonSerializerContext(options); @@ -62,6 +65,9 @@ public override Task DeserializeWrapper(string json, Type type, JsonSeri public override Task DeserializeWrapper(string json, JsonTypeInfo jsonTypeInfo) => throw new NotImplementedException(); + public override Task DeserializeWrapper(string json, JsonTypeInfo jsonTypeInfo) + => throw new NotImplementedException(); + public override Task DeserializeWrapper(string json, Type type, JsonSerializerContext context) => throw new NotImplementedException(); @@ -106,6 +112,7 @@ public override async Task DeserializeWrapper(Stream utf8Json, Type retu } public override Task DeserializeWrapper(Stream utf8Json, JsonTypeInfo jsonTypeInfo) => throw new NotImplementedException(); + public override Task DeserializeWrapper(Stream utf8Json, JsonTypeInfo jsonTypeInfo) => throw new NotImplementedException(); public override async Task SerializeWrapper(Stream stream, T value, JsonSerializerOptions options = null) { @@ -128,6 +135,7 @@ public override async Task SerializeWrapper(Stream stream, object value, Type in } public override Task SerializeWrapper(Stream stream, T value, JsonTypeInfo jsonTypeInfo) => throw new NotImplementedException(); + public override Task SerializeWrapper(Stream stream, object value, JsonTypeInfo jsonTypeInfo) => throw new NotImplementedException(); public override Task SerializeWrapper(Stream stream, object value, Type inputType, JsonSerializerContext context) => throw new NotImplementedException(); public override Task DeserializeWrapper(Stream utf8Json, Type returnType, JsonSerializerContext context) => throw new NotImplementedException(); diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonSerializerWrapper.Reflection.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonSerializerWrapper.Reflection.cs index 49d6babb2fd933..886f96fb71aaf9 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonSerializerWrapper.Reflection.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/JsonSerializerWrapper.Reflection.cs @@ -52,6 +52,12 @@ public override Task SerializeWrapper(T value, JsonTypeInfo jsonTy return Task.FromResult(Encoding.UTF8.GetString(result)); } + public override Task SerializeWrapper(object value, JsonTypeInfo jsonTypeInfo) + { + byte[] result = JsonSerializer.SerializeToUtf8Bytes(value, jsonTypeInfo); + return Task.FromResult(Encoding.UTF8.GetString(result)); + } + public override Task DeserializeWrapper(string json, JsonSerializerOptions options = null) { return Task.FromResult(JsonSerializer.Deserialize(json.AsSpan(), options)); @@ -71,6 +77,11 @@ public override Task DeserializeWrapper(string json, Type type, JsonSeri { return Task.FromResult(JsonSerializer.Deserialize(json.AsSpan(), type, context)); } + + public override Task DeserializeWrapper(string json, JsonTypeInfo jsonTypeInfo) + { + return Task.FromResult(JsonSerializer.Deserialize(json.AsSpan(), jsonTypeInfo)); + } } private class StringSerializerWrapper : JsonSerializerWrapper @@ -97,6 +108,11 @@ public override Task SerializeWrapper(T value, JsonTypeInfo jsonTy return Task.FromResult(JsonSerializer.Serialize(value, jsonTypeInfo)); } + public override Task SerializeWrapper(object value, JsonTypeInfo jsonTypeInfo) + { + return Task.FromResult(JsonSerializer.Serialize(value, jsonTypeInfo)); + } + public override Task DeserializeWrapper(string json, JsonSerializerOptions options = null) { return Task.FromResult(JsonSerializer.Deserialize(json, options)); @@ -116,6 +132,11 @@ public override Task DeserializeWrapper(string json, Type type, JsonSeri { return Task.FromResult(JsonSerializer.Deserialize(json, type, context)); } + + public override Task DeserializeWrapper(string value, JsonTypeInfo jsonTypeInfo) + { + return Task.FromResult(JsonSerializer.Deserialize(value, jsonTypeInfo)); + } } private class AsyncStreamSerializerWrapper : StreamingJsonSerializerWrapper @@ -153,6 +174,11 @@ public override Task SerializeWrapper(Stream stream, T value, JsonTypeInfo return JsonSerializer.SerializeAsync(stream, value, jsonTypeInfo); } + public override Task SerializeWrapper(Stream stream, object value, JsonTypeInfo jsonTypeInfo) + { + return JsonSerializer.SerializeAsync(stream, value, jsonTypeInfo); + } + public override Task SerializeWrapper(Stream stream, object value, Type inputType, JsonSerializerContext context) { return JsonSerializer.SerializeAsync(stream, value, inputType, context); @@ -173,6 +199,11 @@ public override async Task DeserializeWrapper(Stream utf8Json, JsonTypeInf return await JsonSerializer.DeserializeAsync(ResolveReadStream(utf8Json), jsonTypeInfo); } + public override async Task DeserializeWrapper(Stream utf8Json, JsonTypeInfo jsonTypeInfo) + { + return await JsonSerializer.DeserializeAsync(ResolveReadStream(utf8Json), jsonTypeInfo); + } + public override async Task DeserializeWrapper(Stream utf8Json, Type returnType, JsonSerializerContext context) { return await JsonSerializer.DeserializeAsync(ResolveReadStream(utf8Json), returnType, context); @@ -217,6 +248,12 @@ public override Task SerializeWrapper(Stream stream, T value, JsonTypeInfo return Task.CompletedTask; } + public override Task SerializeWrapper(Stream stream, object value, JsonTypeInfo jsonTypeInfo) + { + JsonSerializer.Serialize(stream, value, jsonTypeInfo); + return Task.CompletedTask; + } + public override Task SerializeWrapper(Stream stream, object value, Type inputType, JsonSerializerContext context) { JsonSerializer.Serialize(stream, value, inputType, context); @@ -241,6 +278,12 @@ public override Task DeserializeWrapper(Stream utf8Json, JsonTypeInfo j return Task.FromResult(result); } + public override Task DeserializeWrapper(Stream utf8Json, JsonTypeInfo jsonTypeInfo) + { + object result = JsonSerializer.Deserialize(ResolveReadStream(utf8Json), jsonTypeInfo); + return Task.FromResult(result); + } + public override Task DeserializeWrapper(Stream utf8Json, Type returnType, JsonSerializerContext context) { object result = JsonSerializer.Deserialize(ResolveReadStream(utf8Json), returnType, context); @@ -294,6 +337,17 @@ public override Task SerializeWrapper(T value, JsonTypeInfo jsonTy return Task.FromResult(Encoding.UTF8.GetString(stream.ToArray())); } + public override Task SerializeWrapper(object value, JsonTypeInfo jsonTypeInfo) + { + using MemoryStream stream = new MemoryStream(); + using (Utf8JsonWriter writer = new(stream, OptionsHelpers.GetWriterOptions(jsonTypeInfo?.Options))) + { + JsonSerializer.Serialize(writer, value, jsonTypeInfo); + } + + return Task.FromResult(Encoding.UTF8.GetString(stream.ToArray())); + } + public override Task DeserializeWrapper(string json, JsonSerializerOptions options = null) { Utf8JsonReader reader = new(Encoding.UTF8.GetBytes(json), OptionsHelpers.GetReaderOptions(options)); @@ -312,6 +366,12 @@ public override Task DeserializeWrapper(string json, JsonTypeInfo jsonT return Task.FromResult(JsonSerializer.Deserialize(ref reader, jsonTypeInfo)); } + public override Task DeserializeWrapper(string json, JsonTypeInfo jsonTypeInfo) + { + Utf8JsonReader reader = new(Encoding.UTF8.GetBytes(json), OptionsHelpers.GetReaderOptions(jsonTypeInfo?.Options)); + return Task.FromResult(JsonSerializer.Deserialize(ref reader, jsonTypeInfo)); + } + public override Task DeserializeWrapper(string json, Type type, JsonSerializerContext context) { Utf8JsonReader reader = new(Encoding.UTF8.GetBytes(json), OptionsHelpers.GetReaderOptions(context?.Options)); @@ -345,6 +405,12 @@ public override Task SerializeWrapper(T value, JsonTypeInfo jsonTy return Task.FromResult(GetStringFromDocument(document)); } + public override Task SerializeWrapper(object value, JsonTypeInfo jsonTypeInfo) + { + JsonDocument document = JsonSerializer.SerializeToDocument(value, jsonTypeInfo); + return Task.FromResult(GetStringFromDocument(document)); + } + private string GetStringFromDocument(JsonDocument document) { // Emulate a null return value. @@ -398,6 +464,18 @@ public override Task DeserializeWrapper(string json, JsonTypeInfo jsonT return Task.FromResult(document.Deserialize(jsonTypeInfo)); } + public override Task DeserializeWrapper(string json, JsonTypeInfo jsonTypeInfo) + { + if (json is null) + { + // Emulate a null document for API validation tests. + return Task.FromResult(JsonSerializer.Deserialize(document: null, jsonTypeInfo)); + } + + using JsonDocument document = JsonDocument.Parse(json, OptionsHelpers.GetDocumentOptions(jsonTypeInfo?.Options)); + return Task.FromResult(document.Deserialize(jsonTypeInfo)); + } + public override Task DeserializeWrapper(string json, Type type, JsonSerializerContext context) { if (json is null) @@ -437,6 +515,12 @@ public override Task SerializeWrapper(T value, JsonTypeInfo jsonTy return Task.FromResult(GetStringFromElement(element, jsonTypeInfo?.Options)); } + public override Task SerializeWrapper(object value, JsonTypeInfo jsonTypeInfo) + { + JsonElement element = JsonSerializer.SerializeToElement(value, jsonTypeInfo); + return Task.FromResult(GetStringFromElement(element, jsonTypeInfo?.Options)); + } + private string GetStringFromElement(JsonElement element, JsonSerializerOptions options) { using MemoryStream stream = new MemoryStream(); @@ -465,6 +549,12 @@ public override Task DeserializeWrapper(string json, JsonTypeInfo jsonT return Task.FromResult(document.RootElement.Deserialize(jsonTypeInfo)); } + public override Task DeserializeWrapper(string json, JsonTypeInfo jsonTypeInfo) + { + using JsonDocument document = JsonDocument.Parse(json, OptionsHelpers.GetDocumentOptions(jsonTypeInfo?.Options)); + return Task.FromResult(document.RootElement.Deserialize(jsonTypeInfo)); + } + public override Task DeserializeWrapper(string json, Type type, JsonSerializerContext context) { using JsonDocument document = JsonDocument.Parse(json, OptionsHelpers.GetDocumentOptions(context?.Options)); @@ -528,6 +618,19 @@ public override Task SerializeWrapper(T value, JsonTypeInfo jsonTy return Task.FromResult(node.ToJsonString()); } + public override Task SerializeWrapper(object value, JsonTypeInfo jsonTypeInfo) + { + JsonNode node = JsonSerializer.SerializeToNode(value, jsonTypeInfo); + + // Emulate a null return value. + if (node is null) + { + return Task.FromResult("null"); + } + + return Task.FromResult(node.ToJsonString()); + } + public override Task DeserializeWrapper(string json, JsonSerializerOptions options = null) { if (json is null) @@ -564,6 +667,18 @@ public override Task DeserializeWrapper(string json, JsonTypeInfo jsonT return Task.FromResult(node.Deserialize(jsonTypeInfo)); } + public override Task DeserializeWrapper(string json, JsonTypeInfo jsonTypeInfo) + { + if (json is null) + { + // Emulate a null node for API validation tests. + return Task.FromResult(JsonSerializer.Deserialize(node: null, jsonTypeInfo)); + } + + JsonNode node = JsonNode.Parse(json, OptionsHelpers.GetNodeOptions(jsonTypeInfo?.Options), OptionsHelpers.GetDocumentOptions(jsonTypeInfo?.Options)); + return Task.FromResult(node.Deserialize(jsonTypeInfo)); + } + public override Task DeserializeWrapper(string json, Type type, JsonSerializerContext context) { if (json is null) diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/MetadataTests.JsonSerializer.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/MetadataTests.JsonSerializer.cs index be61553778e964..d0c1cdeb21b5cb 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/MetadataTests.JsonSerializer.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/MetadataTests.JsonSerializer.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text.Json.Serialization.Metadata; using System.Threading.Tasks; using Xunit; @@ -24,6 +25,26 @@ public async Task RoundTripSerializerOverloads() VerifyWeatherForecastWithPOCOs(expected, actual); } + [Fact] + public async Task RoundTripSerializerOverloads_UntypedMetadata() + { + JsonTypeInfo untypedMetadata = JsonContext.Default.WeatherForecastWithPOCOs; + + WeatherForecastWithPOCOs expected = CreateWeatherForecastWithPOCOs(); + string json = await Serializer.SerializeWrapper(expected, untypedMetadata); + WeatherForecastWithPOCOs actual = Assert.IsType(await Serializer.DeserializeWrapper(json, untypedMetadata)); + VerifyWeatherForecastWithPOCOs(expected, actual); + } + + [Fact] + public async Task SerializerOverloads_NullUntypedMetadata_ThrowsArgumentNullException() + { + JsonTypeInfo nullMetadata = null!; + WeatherForecastWithPOCOs expected = CreateWeatherForecastWithPOCOs(); + await AssertExtensions.ThrowsAsync("jsonTypeInfo", () => Serializer.SerializeWrapper(expected, nullMetadata)); + await AssertExtensions.ThrowsAsync("jsonTypeInfo", () => Serializer.DeserializeWrapper("{}", nullMetadata)); + } + private static WeatherForecastWithPOCOs CreateWeatherForecastWithPOCOs() { return new WeatherForecastWithPOCOs diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.DeserializeAsyncEnumerable.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.DeserializeAsyncEnumerable.cs index 38f3122dd69942..ec23f4f69e1b32 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.DeserializeAsyncEnumerable.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/Stream.DeserializeAsyncEnumerable.cs @@ -4,9 +4,10 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; +using System.Text.Json.Serialization.Metadata; using System.Threading; using System.Threading.Tasks; -using System.Text.Json.Serialization.Metadata; using Xunit; namespace System.Text.Json.Serialization.Tests @@ -60,7 +61,7 @@ static byte[] GenerateJsonArray(int count) [Theory] [MemberData(nameof(GetAsyncEnumerableSources))] - public static async Task DeserializeAsyncEnumerable_ReadSourceAsync(IEnumerable source, int bufferSize, bool useJsonTypeInfoOverload) + public static async Task DeserializeAsyncEnumerable_ReadSourceAsync(IEnumerable source, int bufferSize, DeserializeAsyncEnumerableOverload overload) { JsonSerializerOptions options = new JsonSerializerOptions { @@ -71,14 +72,16 @@ public static async Task DeserializeAsyncEnumerable_ReadSourceAsync(IE byte[] data = JsonSerializer.SerializeToUtf8Bytes(source); using var stream = new MemoryStream(data); - List results = await DeserializeAsyncEnumerableWrapper(stream, options, useJsonTypeInfoOverload: useJsonTypeInfoOverload).ToListAsync(); + List results = await DeserializeAsyncEnumerableWrapper(stream, options, overload: overload).ToListAsync(); Assert.Equal(source, results); } [Theory] - [InlineData(false)] - [InlineData(true)] - public static async Task DeserializeAsyncEnumerable_ShouldStreamPartialData(bool useJsonTypeInfoOverload) + [InlineData(DeserializeAsyncEnumerableOverload.JsonSerializerOptions)] + [InlineData(DeserializeAsyncEnumerableOverload.UntypedJsonSerializerOptions)] + [InlineData(DeserializeAsyncEnumerableOverload.JsonTypeInfo)] + [InlineData(DeserializeAsyncEnumerableOverload.UntypedJsonTypeInfo)] + public static async Task DeserializeAsyncEnumerable_ShouldStreamPartialData(DeserializeAsyncEnumerableOverload overload) { string json = JsonSerializer.Serialize(Enumerable.Range(0, 100)); @@ -88,7 +91,7 @@ public static async Task DeserializeAsyncEnumerable_ShouldStreamPartialData(bool DefaultBufferSize = 1 }; - IAsyncEnumerable asyncEnumerable = DeserializeAsyncEnumerableWrapper(stream, options, useJsonTypeInfoOverload: useJsonTypeInfoOverload); + IAsyncEnumerable asyncEnumerable = DeserializeAsyncEnumerableWrapper(stream, options, overload: overload); await using IAsyncEnumerator asyncEnumerator = asyncEnumerable.GetAsyncEnumerator(); for (int i = 0; i < 20; i++) @@ -100,9 +103,11 @@ public static async Task DeserializeAsyncEnumerable_ShouldStreamPartialData(bool } [Theory] - [InlineData(false)] - [InlineData(true)] - public static async Task DeserializeAsyncEnumerable_ShouldTolerateCustomQueueConverters(bool useJsonTypeInfoOverload) + [InlineData(DeserializeAsyncEnumerableOverload.JsonSerializerOptions)] + [InlineData(DeserializeAsyncEnumerableOverload.UntypedJsonSerializerOptions)] + [InlineData(DeserializeAsyncEnumerableOverload.JsonTypeInfo)] + [InlineData(DeserializeAsyncEnumerableOverload.UntypedJsonTypeInfo)] + public static async Task DeserializeAsyncEnumerable_ShouldTolerateCustomQueueConverters(DeserializeAsyncEnumerableOverload overload) { const int expectedCount = 20; @@ -116,7 +121,7 @@ public static async Task DeserializeAsyncEnumerable_ShouldTolerateCustomQueueCon using var stream = new MemoryStream(data); int callbackCount = 0; - await foreach (Queue nestedQueue in DeserializeAsyncEnumerableWrapper>(stream, options, useJsonTypeInfoOverload: useJsonTypeInfoOverload)) + await foreach (Queue nestedQueue in DeserializeAsyncEnumerableWrapper>(stream, options, overload: overload)) { Assert.Equal(1, nestedQueue.Count); Assert.Equal(0, nestedQueue.Peek()); @@ -155,8 +160,11 @@ private class DegenerateQueueConverter : JsonConverter> public static void DeserializeAsyncEnumerable_NullArgument_ThrowsArgumentNullException() { AssertExtensions.Throws("utf8Json", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: null)); + AssertExtensions.Throws("utf8Json", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: null, returnType: typeof(int))); AssertExtensions.Throws("utf8Json", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: null, jsonTypeInfo: ResolveJsonTypeInfo())); + AssertExtensions.Throws("utf8Json", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: null, jsonTypeInfo: ResolveJsonTypeInfo(typeof(int)))); AssertExtensions.Throws("jsonTypeInfo", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: new MemoryStream(), jsonTypeInfo: null)); + AssertExtensions.Throws("jsonTypeInfo", () => JsonSerializer.DeserializeAsyncEnumerable(utf8Json: new MemoryStream(), jsonTypeInfo: null)); } [Theory] @@ -174,16 +182,18 @@ public static async Task DeserializeAsyncEnumerable_NotARootLevelJsonArray_Throw } { - IAsyncEnumerable asyncEnumerable = JsonSerializer.DeserializeAsyncEnumerable(utf8Json, ResolveJsonTypeInfo()); + IAsyncEnumerable asyncEnumerable = JsonSerializer.DeserializeAsyncEnumerable(utf8Json, ResolveJsonTypeInfo()); await using IAsyncEnumerator enumerator = asyncEnumerable.GetAsyncEnumerator(); await Assert.ThrowsAsync(async () => await enumerator.MoveNextAsync()); } } [Theory] - [InlineData(false)] - [InlineData(true)] - public static async Task DeserializeAsyncEnumerable_CancellationToken_ThrowsOnCancellation(bool useJsonTypeInfoOverload) + [InlineData(DeserializeAsyncEnumerableOverload.JsonSerializerOptions)] + [InlineData(DeserializeAsyncEnumerableOverload.UntypedJsonSerializerOptions)] + [InlineData(DeserializeAsyncEnumerableOverload.JsonTypeInfo)] + [InlineData(DeserializeAsyncEnumerableOverload.UntypedJsonTypeInfo)] + public static async Task DeserializeAsyncEnumerable_CancellationToken_ThrowsOnCancellation(DeserializeAsyncEnumerableOverload overload) { JsonSerializerOptions options = new JsonSerializerOptions { @@ -194,7 +204,7 @@ public static async Task DeserializeAsyncEnumerable_CancellationToken_ThrowsOnCa var token = new CancellationToken(canceled: true); using var stream = new MemoryStream(data); - var cancellableAsyncEnumerable = DeserializeAsyncEnumerableWrapper(stream, options, token, useJsonTypeInfoOverload); + var cancellableAsyncEnumerable = DeserializeAsyncEnumerableWrapper(stream, options, token, overload); await Assert.ThrowsAsync(async () => { @@ -205,9 +215,11 @@ await Assert.ThrowsAsync(async () => } [Theory] - [InlineData(false)] - [InlineData(true)] - public static async Task DeserializeAsyncEnumerable_EnumeratorWithCancellationToken_ThrowsOnCancellation(bool useJsonTypeInfoOverload) + [InlineData(DeserializeAsyncEnumerableOverload.JsonSerializerOptions)] + [InlineData(DeserializeAsyncEnumerableOverload.UntypedJsonSerializerOptions)] + [InlineData(DeserializeAsyncEnumerableOverload.JsonTypeInfo)] + [InlineData(DeserializeAsyncEnumerableOverload.UntypedJsonTypeInfo)] + public static async Task DeserializeAsyncEnumerable_EnumeratorWithCancellationToken_ThrowsOnCancellation(DeserializeAsyncEnumerableOverload overload) { JsonSerializerOptions options = new JsonSerializerOptions { @@ -218,7 +230,7 @@ public static async Task DeserializeAsyncEnumerable_EnumeratorWithCancellationTo var token = new CancellationToken(canceled: true); using var stream = new MemoryStream(data); - var cancellableAsyncEnumerable = DeserializeAsyncEnumerableWrapper(stream, options, useJsonTypeInfoOverload: useJsonTypeInfoOverload).WithCancellation(token); + var cancellableAsyncEnumerable = DeserializeAsyncEnumerableWrapper(stream, options, overload: overload).WithCancellation(token); await Assert.ThrowsAsync(async () => { @@ -230,31 +242,55 @@ await Assert.ThrowsAsync(async () => public static IEnumerable GetAsyncEnumerableSources() { - yield return WrapArgs(Enumerable.Empty(), 1, false); - yield return WrapArgs(Enumerable.Empty(), 1, true); - yield return WrapArgs(Enumerable.Range(0, 20), 1, false); - yield return WrapArgs(Enumerable.Range(0, 100), 20, false); - yield return WrapArgs(Enumerable.Range(0, 100).Select(i => $"lorem ipsum dolor: {i}"), 500, false); - yield return WrapArgs(Enumerable.Range(0, 100).Select(i => $"lorem ipsum dolor: {i}"), 500, true); - yield return WrapArgs(Enumerable.Range(0, 10).Select(i => new { Field1 = i, Field2 = $"lorem ipsum dolor: {i}", Field3 = i % 2 == 0 }), 100, false); - yield return WrapArgs(Enumerable.Range(0, 10).Select(i => new { Field1 = i, Field2 = $"lorem ipsum dolor: {i}", Field3 = i % 2 == 0 }), 100, false); - yield return WrapArgs(Enumerable.Range(0, 100).Select(i => new { Field1 = i, Field2 = $"lorem ipsum dolor: {i}", Field3 = i % 2 == 0 }), 500, false); - - static object[] WrapArgs(IEnumerable source, int bufferSize, bool useJsonTypeInfoOverload) => new object[] { source, bufferSize, useJsonTypeInfoOverload }; + yield return WrapArgs(Enumerable.Empty(), 1, DeserializeAsyncEnumerableOverload.JsonSerializerOptions); + yield return WrapArgs(Enumerable.Empty(), 1, DeserializeAsyncEnumerableOverload.UntypedJsonSerializerOptions); + yield return WrapArgs(Enumerable.Empty(), 1, DeserializeAsyncEnumerableOverload.JsonTypeInfo); + yield return WrapArgs(Enumerable.Empty(), 1, DeserializeAsyncEnumerableOverload.UntypedJsonTypeInfo); + yield return WrapArgs(Enumerable.Range(0, 20), 1, DeserializeAsyncEnumerableOverload.JsonSerializerOptions); + yield return WrapArgs(Enumerable.Range(0, 100), 20, DeserializeAsyncEnumerableOverload.JsonSerializerOptions); + yield return WrapArgs(Enumerable.Range(0, 100).Select(i => $"lorem ipsum dolor: {i}"), 500, DeserializeAsyncEnumerableOverload.JsonSerializerOptions); + yield return WrapArgs(Enumerable.Range(0, 100).Select(i => $"lorem ipsum dolor: {i}"), 500, DeserializeAsyncEnumerableOverload.JsonTypeInfo); + yield return WrapArgs(Enumerable.Range(0, 10).Select(i => new { Field1 = i, Field2 = $"lorem ipsum dolor: {i}", Field3 = i % 2 == 0 }), 100, DeserializeAsyncEnumerableOverload.JsonSerializerOptions); + yield return WrapArgs(Enumerable.Range(0, 10).Select(i => new { Field1 = i, Field2 = $"lorem ipsum dolor: {i}", Field3 = i % 2 == 0 }), 100, DeserializeAsyncEnumerableOverload.UntypedJsonSerializerOptions); + yield return WrapArgs(Enumerable.Range(0, 10).Select(i => new { Field1 = i, Field2 = $"lorem ipsum dolor: {i}", Field3 = i % 2 == 0 }), 100, DeserializeAsyncEnumerableOverload.JsonTypeInfo); + yield return WrapArgs(Enumerable.Range(0, 10).Select(i => new { Field1 = i, Field2 = $"lorem ipsum dolor: {i}", Field3 = i % 2 == 0 }), 100, DeserializeAsyncEnumerableOverload.UntypedJsonTypeInfo); + yield return WrapArgs(Enumerable.Range(0, 100).Select(i => new { Field1 = i, Field2 = $"lorem ipsum dolor: {i}", Field3 = i % 2 == 0 }), 500, DeserializeAsyncEnumerableOverload.JsonSerializerOptions); + + static object[] WrapArgs(IEnumerable source, int bufferSize, DeserializeAsyncEnumerableOverload overload) => new object[] { source, bufferSize, overload }; } - private static IAsyncEnumerable DeserializeAsyncEnumerableWrapper(Stream stream, JsonSerializerOptions options = null, CancellationToken cancellationToken = default, bool useJsonTypeInfoOverload = false) + public enum DeserializeAsyncEnumerableOverload { JsonSerializerOptions, UntypedJsonSerializerOptions, JsonTypeInfo, UntypedJsonTypeInfo }; + + private static IAsyncEnumerable DeserializeAsyncEnumerableWrapper(Stream stream, JsonSerializerOptions options = null, CancellationToken cancellationToken = default, DeserializeAsyncEnumerableOverload overload = DeserializeAsyncEnumerableOverload.JsonSerializerOptions) { - return useJsonTypeInfoOverload - ? JsonSerializer.DeserializeAsyncEnumerable(stream, ResolveJsonTypeInfo(options), cancellationToken) - : JsonSerializer.DeserializeAsyncEnumerable(stream, options, cancellationToken); + return overload switch + { + DeserializeAsyncEnumerableOverload.JsonTypeInfo => JsonSerializer.DeserializeAsyncEnumerable(stream, ResolveJsonTypeInfo(options), cancellationToken), + DeserializeAsyncEnumerableOverload.UntypedJsonTypeInfo => Cast(JsonSerializer.DeserializeAsyncEnumerable(stream, ResolveJsonTypeInfo(typeof(T), options), cancellationToken)), + DeserializeAsyncEnumerableOverload.UntypedJsonSerializerOptions => Cast(JsonSerializer.DeserializeAsyncEnumerable(stream, typeof(T), options, cancellationToken)), + DeserializeAsyncEnumerableOverload.JsonSerializerOptions or _ => JsonSerializer.DeserializeAsyncEnumerable(stream, options, cancellationToken), + }; + + static async IAsyncEnumerable Cast(IAsyncEnumerable source, [EnumeratorCancellation] CancellationToken token = default) + { + await foreach (object item in source.WithCancellation(token)) + { + yield return (T)item; + } + } } private static JsonTypeInfo ResolveJsonTypeInfo(JsonSerializerOptions? options = null) + { + return (JsonTypeInfo)ResolveJsonTypeInfo(typeof(T), options); + } + + private static JsonTypeInfo ResolveJsonTypeInfo(Type type, JsonSerializerOptions? options = null) { options ??= JsonSerializerOptions.Default; - JsonSerializer.Serialize(42, options); // Lock the options instance before initializing metadata - return (JsonTypeInfo)options.TypeInfoResolver.GetTypeInfo(typeof(T), options); + options.TypeInfoResolver ??= new DefaultJsonTypeInfoResolver(); + options.MakeReadOnly(); // Lock the options instance before initializing metadata + return options.TypeInfoResolver.GetTypeInfo(type, options); } private static async Task> ToListAsync(this IAsyncEnumerable source)