diff --git a/.openpublishing.redirection.standard.json b/.openpublishing.redirection.standard.json index e6a23d26cec2a..f6de36a45fed4 100644 --- a/.openpublishing.redirection.standard.json +++ b/.openpublishing.redirection.standard.json @@ -739,6 +739,11 @@ "source_path_from_root": "/docs/standard/serialization/system-text-json-use-dom-utf8jsonreader-utf8jsonwriter.md", "redirect_url": "/dotnet/standard/serialization/system-text-json/use-dom" }, + { + "source_path_from_root": "/docs/standard/serialization/system-text-json/json-schema-exporter.md", + "redirect_url": "/dotnet/standard/serialization/system-text-json/extract-schema", + "redirect_document_id": true + }, { "source_path_from_root": "/docs/standard/serialization/system-text-json/use-dom-utf8jsonreader-utf8jsonwriter.md", "redirect_url": "/dotnet/standard/serialization/system-text-json/use-dom", diff --git a/docs/core/whats-new/dotnet-9/libraries.md b/docs/core/whats-new/dotnet-9/libraries.md index f0d0bb763c259..aeb42b7cee2dd 100644 --- a/docs/core/whats-new/dotnet-9/libraries.md +++ b/docs/core/whats-new/dotnet-9/libraries.md @@ -493,33 +493,7 @@ If you want to serialize with the [default options that ASP.NET Core uses](../.. JSON is frequently used to represent types in method signatures as part of remote procedure–calling schemes. It's used, for example, as part of OpenAPI specifications, or as part of tool calling with AI services like those from OpenAI. Developers can serialize and deserialize .NET types as JSON using . But they also need to be able to get a JSON schema that describes the shape of the .NET type (that is, describes the shape of what would be serialized and what can be deserialized). now provides the type, which supports generating a JSON schema that represents a .NET type. -The following code generates a JSON schema from a type. - -:::code language="csharp" source="../snippets/dotnet-9/csharp/Serialization.cs" id="Schema"::: - -The type is defined as follows: - -:::code language="csharp" source="../snippets/dotnet-9/csharp/Serialization.cs" id="Book"::: - -The generated schema is: - -```json -{ - "type": ["object", "null"], - "properties": { - "Title": { - "type": "string" - }, - "Author": { - "type": ["string", "null"] - }, - "PublishYear": { - "type": "integer" - } - }, - "required": ["Title"] -} -``` +For more information, see [JSON schema exporter](../../../standard/serialization/system-text-json/extract-schema.md). ### Respect nullable annotations @@ -588,50 +562,9 @@ enum MyEnum ### Stream multiple JSON documents - now supports reading multiple, whitespace-separated JSON documents from a single buffer or stream. By default, the reader throws an exception if it detects any non-whitespace characters that are trailing the first top-level document. You can change this behavior using the flag: - -```csharp -JsonReaderOptions options = new() { AllowMultipleValues = true }; -Utf8JsonReader reader = new("null {} 1 \r\n [1,2,3]"u8, options); - -reader.Read(); -Console.WriteLine(reader.TokenType); // Null - -reader.Read(); -Console.WriteLine(reader.TokenType); // StartObject -reader.Skip(); - -reader.Read(); -Console.WriteLine(reader.TokenType); // Number + now supports reading multiple, whitespace-separated JSON documents from a single buffer or stream. By default, the reader throws an exception if it detects any non-whitespace characters that are trailing the first top-level document. You can change this behavior using the flag. -reader.Read(); -Console.WriteLine(reader.TokenType); // StartArray -reader.Skip(); - -Console.WriteLine(reader.Read()); // False -``` - -This flag also makes it possible to read JSON from payloads that might contain trailing data that's invalid JSON: - -```csharp -Utf8JsonReader reader = new("[1,2,3] "u8, new() { AllowMultipleValues = true }); - -reader.Read(); -reader.Skip(); // Success -reader.Read(); // throws JsonReaderException -``` - -When it comes to streaming deserialization, a new overload makes streaming multiple top-level values possible. By default, the method attempts to stream elements that are contained in a top-level JSON array. You can toggle this behavior using the new `topLevelValues` flag: - -```csharp -ReadOnlySpan utf8Json = """[0] [0,1] [0,1,1] [0,1,1,2] [0,1,1,2,3]"""u8; -using var stream = new MemoryStream(utf8Json.ToArray()); - -await foreach (int[] item in JsonSerializer.DeserializeAsyncEnumerable(stream, topLevelValues: true)) -{ - Console.WriteLine(item.Length); -} -``` +For more information, see [Read multiple JSON documents](../../../standard/serialization/system-text-json/use-utf8jsonreader.md#read-multiple-json-documents). ## Spans diff --git a/docs/fundamentals/toc.yml b/docs/fundamentals/toc.yml index e221ef35da1f6..d1bdcd355c4b0 100644 --- a/docs/fundamentals/toc.yml +++ b/docs/fundamentals/toc.yml @@ -786,7 +786,7 @@ items: - name: Customize contracts href: ../standard/serialization/system-text-json/custom-contracts.md - name: Extract JSON schema - href: ../standard/serialization/system-text-json/json-schema-exporter.md + href: ../standard/serialization/system-text-json/extract-schema.md - name: XML and SOAP serialization items: - name: Overview diff --git a/docs/standard/serialization/system-text-json/json-schema-exporter.md b/docs/standard/serialization/system-text-json/extract-schema.md similarity index 82% rename from docs/standard/serialization/system-text-json/json-schema-exporter.md rename to docs/standard/serialization/system-text-json/extract-schema.md index 005ffead49390..addf82e24d349 100644 --- a/docs/standard/serialization/system-text-json/json-schema-exporter.md +++ b/docs/standard/serialization/system-text-json/extract-schema.md @@ -8,7 +8,7 @@ dev_langs: # JSON schema exporter -The new class lets you extract [JSON schema](https://json-schema.org/) documents from .NET types using either a or instance. The resultant schema provides a specification of the JSON serialization contract for the type. +The class, introduced in .NET 9, lets you extract [JSON schema](https://json-schema.org/) documents from .NET types using either a or instance. The resultant schema provides a specification of the JSON serialization contract for the .NET type. The schema describes the shape of what would be serialized and what can be deserialized. The following code snippet shows an example. diff --git a/docs/standard/serialization/system-text-json/handle-overflow.md b/docs/standard/serialization/system-text-json/handle-overflow.md index 2d35bdee3f918..57843048cbe1f 100644 --- a/docs/standard/serialization/system-text-json/handle-overflow.md +++ b/docs/standard/serialization/system-text-json/handle-overflow.md @@ -14,7 +14,7 @@ helpviewer_keywords: ms.topic: how-to --- -# How to handle overflow JSON or use JsonElement or JsonNode in System.Text.Json +# How to handle overflow JSON or use JsonElement or JsonNode This article shows how to handle overflow JSON with the namespace. It also shows how to deserialize into or , as an alternative for other scenarios where the target type might not perfectly match all of the JSON being deserialized. @@ -86,7 +86,7 @@ The following example shows a round trip from JSON to a deserialized object and ## Deserialize into JsonElement or JsonNode -If you just want to be flexible about what JSON is acceptable for a particular property, an alternative is to deserialize into or . Any valid JSON property can be deserialized into `JsonElement` or `JsonNode`. Choose `JsonElement` to create an immutable object or `JsonNode` to create a mutable object. +If you just want to be flexible about what JSON is acceptable for a particular property, an alternative is to deserialize into or . Any valid JSON property can be deserialized into `JsonElement` or `JsonNode`. Choose `JsonElement` to create an *immutable* object or `JsonNode` to create a *mutable* object. The following example shows a round trip from JSON and back to JSON for a class that includes properties of type `JsonElement` and `JsonNode`. diff --git a/docs/standard/serialization/system-text-json/how-to.md b/docs/standard/serialization/system-text-json/how-to.md index 14156bf0c0809..90ef05e1cc755 100644 --- a/docs/standard/serialization/system-text-json/how-to.md +++ b/docs/standard/serialization/system-text-json/how-to.md @@ -33,7 +33,7 @@ The following example creates JSON as a string: :::code language="csharp" source="snippets/how-to/csharp/SerializeBasic.cs" id="all" highlight="23"::: :::code language="vb" source="snippets/how-to/vb/RoundtripToString.vb" id="Serialize"::: -The JSON output is minified (whitespace, indentation, and new-line characters are removed) by default. +The JSON output is *minified* (whitespace, indentation, and new-line characters are removed) by default. The following example uses synchronous code to create a JSON file: @@ -104,6 +104,8 @@ To pretty-print the JSON output, set and . + > [!TIP] > If you use `JsonSerializerOptions` repeatedly with the same options, don't create a new `JsonSerializerOptions` instance each time you use it. Reuse the same instance for every call. For more information, see [Reuse JsonSerializerOptions instances](configure-options.md#reuse-jsonserializeroptions-instances). diff --git a/docs/standard/serialization/system-text-json/migrate-from-newtonsoft.md b/docs/standard/serialization/system-text-json/migrate-from-newtonsoft.md index 31aa654d79100..c21a4168649bd 100644 --- a/docs/standard/serialization/system-text-json/migrate-from-newtonsoft.md +++ b/docs/standard/serialization/system-text-json/migrate-from-newtonsoft.md @@ -782,8 +782,8 @@ If you need to continue to use `Newtonsoft.Json` for certain target frameworks, Starting in .NET 9, you can customize the indentation character and size for using options exposed by the struct: -* `JsonWriterOptions.IndentCharacter` -* `JsonWriterOptions.IndentSize` +* +* ::: zone-end diff --git a/docs/standard/serialization/system-text-json/snippets/how-to-contd/csharp/ImmutableTypes.cs b/docs/standard/serialization/system-text-json/snippets/how-to-contd/csharp/ImmutableTypes.cs index 9a43f34bb9a0f..d0ae803c2eae8 100644 --- a/docs/standard/serialization/system-text-json/snippets/how-to-contd/csharp/ImmutableTypes.cs +++ b/docs/standard/serialization/system-text-json/snippets/how-to-contd/csharp/ImmutableTypes.cs @@ -8,7 +8,7 @@ public struct Forecast public DateTime Date { get; } public int TemperatureC { get; } public string Summary { get; } - + [JsonConstructor] public Forecast(DateTime date, int temperatureC, string summary) => (Date, TemperatureC, Summary) = (date, temperatureC, summary); @@ -27,7 +27,7 @@ public static void Main() """; Console.WriteLine($"Input JSON: {json}"); - var options = new JsonSerializerOptions(JsonSerializerDefaults.Web); + var options = JsonSerializerOptions.Web; Forecast forecast = JsonSerializer.Deserialize(json, options); diff --git a/docs/standard/serialization/system-text-json/snippets/how-to-contd/csharp/ImmutableTypesCtorParms.cs b/docs/standard/serialization/system-text-json/snippets/how-to-contd/csharp/ImmutableTypesCtorParms.cs index fb0a5738f4101..c71418fa67b20 100644 --- a/docs/standard/serialization/system-text-json/snippets/how-to-contd/csharp/ImmutableTypesCtorParms.cs +++ b/docs/standard/serialization/system-text-json/snippets/how-to-contd/csharp/ImmutableTypesCtorParms.cs @@ -9,7 +9,7 @@ public readonly struct Forecast [JsonPropertyName("celsius")] public int TemperatureC { get; } public string Summary { get; } - + [JsonConstructor] public Forecast(DateTime date, int temperatureC, string summary) => (Date, TemperatureC, Summary) = (date, temperatureC, summary); @@ -28,7 +28,7 @@ public static void Main() """; Console.WriteLine($"Input JSON: {json}"); - var options = new JsonSerializerOptions(JsonSerializerDefaults.Web); + var options = JsonSerializerOptions.Web; Forecast forecast = JsonSerializer.Deserialize(json, options); diff --git a/docs/standard/serialization/system-text-json/snippets/how-to-contd/csharp/SystemTextJsonHowTo.csproj b/docs/standard/serialization/system-text-json/snippets/how-to-contd/csharp/SystemTextJsonHowTo.csproj index 0d3ae03a50b03..cd08d4e634e32 100644 --- a/docs/standard/serialization/system-text-json/snippets/how-to-contd/csharp/SystemTextJsonHowTo.csproj +++ b/docs/standard/serialization/system-text-json/snippets/how-to-contd/csharp/SystemTextJsonHowTo.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 SystemTextJsonHowTo.Program enable enable diff --git a/docs/standard/serialization/system-text-json/snippets/how-to-contd/vb/ImmutableTypes.vb b/docs/standard/serialization/system-text-json/snippets/how-to-contd/vb/ImmutableTypes.vb index 94d81696f638a..1e10095332595 100644 --- a/docs/standard/serialization/system-text-json/snippets/how-to-contd/vb/ImmutableTypes.vb +++ b/docs/standard/serialization/system-text-json/snippets/how-to-contd/vb/ImmutableTypes.vb @@ -23,15 +23,13 @@ Namespace ImmutableTypes Dim json As String = "{""date"":""2020-09-06T11:31:01.923395-07:00"",""temperatureC"":-1,""summary"":""Cold""}" Console.WriteLine($"Input JSON: {json}") - Dim options As New JsonSerializerOptions(JsonSerializerDefaults.Web) - - Dim forecast1 As Forecast = JsonSerializer.Deserialize(Of Forecast)(json, options) + Dim forecast1 As Forecast = JsonSerializer.Deserialize(Of Forecast)(json, JsonSerializerOptions.Web) Console.WriteLine($"forecast.Date: {forecast1.[Date]}") Console.WriteLine($"forecast.TemperatureC: {forecast1.TemperatureC}") Console.WriteLine($"forecast.Summary: {forecast1.Summary}") - Dim roundTrippedJson As String = JsonSerializer.Serialize(forecast1, options) + Dim roundTrippedJson As String = JsonSerializer.Serialize(forecast1, JsonSerializerOptions.Web) Console.WriteLine($"Output JSON: {roundTrippedJson}") End Sub diff --git a/docs/standard/serialization/system-text-json/snippets/how-to-contd/vb/Program.vb b/docs/standard/serialization/system-text-json/snippets/how-to-contd/vb/Program.vb index bccc029616c17..fd18f335e221f 100644 --- a/docs/standard/serialization/system-text-json/snippets/how-to-contd/vb/Program.vb +++ b/docs/standard/serialization/system-text-json/snippets/how-to-contd/vb/Program.vb @@ -14,49 +14,49 @@ ImmutableTypes.Program.Main() Console.WriteLine() - Console.WriteLine("======== Field support =========") - Fields.Program.Main() - Console.WriteLine() + 'Console.WriteLine("======== Field support =========") + 'Fields.Program.Main() + 'Console.WriteLine() - Console.WriteLine("======== Non-string key dictionary =========") - NonStringKeyDictionary.Program.Main() - Console.WriteLine() + 'Console.WriteLine("======== Non-string key dictionary =========") + 'NonStringKeyDictionary.Program.Main() + 'Console.WriteLine() - Console.WriteLine("======== HttpClient extension methods =========") - Await HttpClientExtensionMethods.Program.Main() - Console.WriteLine() + 'Console.WriteLine("======== HttpClient extension methods =========") + 'Await HttpClientExtensionMethods.Program.Main() + 'Console.WriteLine() - Console.WriteLine("======== Ignore value type default on serialize =========") - IgnoreValueDefaultOnSerialize.Program.Main() - Console.WriteLine() + 'Console.WriteLine("======== Ignore value type default on serialize =========") + 'IgnoreValueDefaultOnSerialize.Program.Main() + 'Console.WriteLine() - Console.WriteLine("======== Ignore null on serialize =========") - IgnoreNullOnSerialize.Program.Main() - Console.WriteLine() + 'Console.WriteLine("======== Ignore null on serialize =========") + 'IgnoreNullOnSerialize.Program.Main() + 'Console.WriteLine() - Console.WriteLine("======== Conditionally ignore selected properties on serialize =========") - JsonIgnoreAttributeExample.Program.Main() - Console.WriteLine() + 'Console.WriteLine("======== Conditionally ignore selected properties on serialize =========") + 'JsonIgnoreAttributeExample.Program.Main() + 'Console.WriteLine() - Console.WriteLine("======== Non-public accessors =========") - NonPublicAccessors.Program.Main() - Console.WriteLine() + 'Console.WriteLine("======== Non-public accessors =========") + 'NonPublicAccessors.Program.Main() + 'Console.WriteLine() - Console.WriteLine("======== Copy options instance =========") - CopyOptions.Program.Main() - Console.WriteLine() + 'Console.WriteLine("======== Copy options instance =========") + 'CopyOptions.Program.Main() + 'Console.WriteLine() - Console.WriteLine("======== Create options instance with specified defaults =========") - OptionsDefaults.Program.Main() - Console.WriteLine() + 'Console.WriteLine("======== Create options instance with specified defaults =========") + 'OptionsDefaults.Program.Main() + 'Console.WriteLine() - Console.WriteLine("======== Quoted numbers =========") - QuotedNumbers.Program.Main() - Console.WriteLine() + 'Console.WriteLine("======== Quoted numbers =========") + 'QuotedNumbers.Program.Main() + 'Console.WriteLine() - Console.WriteLine("======== GuidReferenceResolver =========") - GuidReferenceResolverExample.Program.Main() - Console.WriteLine() + 'Console.WriteLine("======== GuidReferenceResolver =========") + 'GuidReferenceResolverExample.Program.Main() + 'Console.WriteLine() End Function End Module diff --git a/docs/standard/serialization/system-text-json/snippets/how-to-contd/vb/SystemTextJsonHowTo.vbproj b/docs/standard/serialization/system-text-json/snippets/how-to-contd/vb/SystemTextJsonHowTo.vbproj index 8fe398fcb8f79..8756180267209 100644 --- a/docs/standard/serialization/system-text-json/snippets/how-to-contd/vb/SystemTextJsonHowTo.vbproj +++ b/docs/standard/serialization/system-text-json/snippets/how-to-contd/vb/SystemTextJsonHowTo.vbproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 SystemTextJsonHowTo.SystemTextJsonHowTo.Program diff --git a/docs/standard/serialization/system-text-json/snippets/how-to/csharp/JsonDocumentDataAccess.cs b/docs/standard/serialization/system-text-json/snippets/how-to/csharp/JsonDocumentDataAccess.cs index a45612da38e4d..f641658178940 100644 --- a/docs/standard/serialization/system-text-json/snippets/how-to/csharp/JsonDocumentDataAccess.cs +++ b/docs/standard/serialization/system-text-json/snippets/how-to/csharp/JsonDocumentDataAccess.cs @@ -11,7 +11,10 @@ public static void Run() AverageGrades(jsonString); AverageGrades_Alternative(jsonString); + + Compare(); } + private static void AverageGrades(string jsonString) { // @@ -40,6 +43,7 @@ private static void AverageGrades(string jsonString) Console.WriteLine($"Average grade : {average}"); // } + private static void AverageGrades_Alternative(string jsonString) { // @@ -70,5 +74,15 @@ private static void AverageGrades_Alternative(string jsonString) Console.WriteLine($"Average grade : {average}"); // } + + private static void Compare() + { + // + JsonElement left = JsonDocument.Parse("10e-3").RootElement; + JsonElement right = JsonDocument.Parse("0.01").RootElement; + bool equal = JsonElement.DeepEquals(left, right); + Console.WriteLine(equal); // True. + // + } } } diff --git a/docs/standard/serialization/system-text-json/snippets/how-to/csharp/Program.cs b/docs/standard/serialization/system-text-json/snippets/how-to/csharp/Program.cs index 14c987b2df55b..c926c8ce15cc9 100644 --- a/docs/standard/serialization/system-text-json/snippets/how-to/csharp/Program.cs +++ b/docs/standard/serialization/system-text-json/snippets/how-to/csharp/Program.cs @@ -6,145 +6,145 @@ public class Program { static async Task Main(string[] args) { - Console.WriteLine("\n============================= Roundtrip to DateOnly and TimeOnly props.\n"); - RoundtripDateOnly.Run(); + //Console.WriteLine("\n============================= Roundtrip to DateOnly and TimeOnly props.\n"); + //RoundtripDateOnly.Run(); - Console.WriteLine("\n============================= Roundtrip to string\n"); - SerializeBasic.Program.Main(); - SerializeWithGenericParameter.Program.Main(); - SerializeWriteIndented.Program.Main(); - SerializeExtra.Program.Main(); - DeserializeExtra.Program.Main(); + //Console.WriteLine("\n============================= Roundtrip to string\n"); + //SerializeBasic.Program.Main(); + //SerializeWithGenericParameter.Program.Main(); + //SerializeWriteIndented.Program.Main(); + //SerializeExtra.Program.Main(); + //DeserializeExtra.Program.Main(); - Console.WriteLine("\n============================= Roundtrip to UTF-8 byte array\n"); - RoundtripToUtf8Bytes1.Program.Main(); - RoundtripToUtf8Bytes2.Program.Main(); - RoundtripToUtf8Bytes3.Program.Main(); + //Console.WriteLine("\n============================= Roundtrip to UTF-8 byte array\n"); + //RoundtripToUtf8Bytes1.Program.Main(); + //RoundtripToUtf8Bytes2.Program.Main(); + //RoundtripToUtf8Bytes3.Program.Main(); - Console.WriteLine("\n============================= Roundtrip to file\n"); - SerializeToFile.Program.Main(); - DeserializeFromFile.Program.Main(); + //Console.WriteLine("\n============================= Roundtrip to file\n"); + //SerializeToFile.Program.Main(); + //DeserializeFromFile.Program.Main(); - Console.WriteLine("\n============================= Roundtrip to file async\n"); - await SerializeToFileAsync.Program.Main(); - await DeserializeFromFileAsync.Program.Main(); + //Console.WriteLine("\n============================= Roundtrip to file async\n"); + //await SerializeToFileAsync.Program.Main(); + //await DeserializeFromFileAsync.Program.Main(); - Console.WriteLine("\n============================= Roundtrip camel case property names\n"); - RoundtripCamelCasePropertyNames.Run(); + //Console.WriteLine("\n============================= Roundtrip camel case property names\n"); + //RoundtripCamelCasePropertyNames.Run(); - Console.WriteLine("\n============================= Roundtrip custom property naming policy\n"); - RoundtripPropertyNamingPolicy.Run(); + //Console.WriteLine("\n============================= Roundtrip custom property naming policy\n"); + //RoundtripPropertyNamingPolicy.Run(); - Console.WriteLine("\n============================= Roundtrip custom property name by attribute\n"); - RoundtripPropertyNamesByAttribute.Run(); + //Console.WriteLine("\n============================= Roundtrip custom property name by attribute\n"); + //RoundtripPropertyNamesByAttribute.Run(); - Console.WriteLine("\n============================= Roundtrip extension data\n"); - RoundtripExtensionData.Program.Main(); - RoundtripJsonElement.Program.Main(); + //Console.WriteLine("\n============================= Roundtrip extension data\n"); + //RoundtripExtensionData.Program.Main(); + //RoundtripJsonElement.Program.Main(); - Console.WriteLine("\n============================= Roundtrip enum as string\n"); - RoundtripEnumAsString.Run(); + //Console.WriteLine("\n============================= Roundtrip enum as string\n"); + //RoundtripEnumAsString.Run(); - Console.WriteLine("\n============================= Roundtrip enum using JsonConverterAttribute\n"); - RoundtripEnumUsingConverterAttribute.Run(); + //Console.WriteLine("\n============================= Roundtrip enum using JsonConverterAttribute\n"); + //RoundtripEnumUsingConverterAttribute.Run(); - Console.WriteLine("\n============================= Roundtrip enum using source generation\n"); - RoundtripEnumUsingSourceGeneration.Run(); + //Console.WriteLine("\n============================= Roundtrip enum using source generation\n"); + //RoundtripEnumUsingSourceGeneration.Run(); - Console.WriteLine("\n============================= Roundtrip enum using source generation - blanket policy\n"); - RoundtripEnumUsingSourceGeneration2.Run(); + //Console.WriteLine("\n============================= Roundtrip enum using source generation - blanket policy\n"); + //RoundtripEnumUsingSourceGeneration2.Run(); - Console.WriteLine("\n============================= Roundtrip Stack\n"); - RoundtripStackOfT.Run(); + //Console.WriteLine("\n============================= Roundtrip Stack\n"); + //RoundtripStackOfT.Run(); - Console.WriteLine("\n============================= Serialize polymorphic\n"); - SerializePolymorphic.Run(); + //Console.WriteLine("\n============================= Serialize polymorphic\n"); + //SerializePolymorphic.Run(); - Console.WriteLine("\n============================= Serialize custom encoding\n"); - SerializeCustomEncoding.Run(); + //Console.WriteLine("\n============================= Serialize custom encoding\n"); + //SerializeCustomEncoding.Run(); - Console.WriteLine("\n============================= Serialize exclude null value properties\n"); - SerializeExcludeNullValueProperties.Run(); + //Console.WriteLine("\n============================= Serialize exclude null value properties\n"); + //SerializeExcludeNullValueProperties.Run(); - Console.WriteLine("\n============================= Serialize exclude properties by attribute\n"); - SerializeExcludePropertiesByAttribute.Run(); + //Console.WriteLine("\n============================= Serialize exclude properties by attribute\n"); + //SerializeExcludePropertiesByAttribute.Run(); - Console.WriteLine("\n============================= Serialize exclude read-only properties\n"); - SerializeExcludeReadOnlyProperties.Run(); + //Console.WriteLine("\n============================= Serialize exclude read-only properties\n"); + //SerializeExcludeReadOnlyProperties.Run(); - Console.WriteLine("\n============================= Serialize camel case Dictionary keys\n"); - SerializeCamelCaseDictionaryKeys.Run(); + //Console.WriteLine("\n============================= Serialize camel case Dictionary keys\n"); + //SerializeCamelCaseDictionaryKeys.Run(); - Console.WriteLine("\n============================= Deserialize case-insensitive\n"); - DeserializeCaseInsensitive.Run(); + //Console.WriteLine("\n============================= Deserialize case-insensitive\n"); + //DeserializeCaseInsensitive.Run(); - Console.WriteLine("\n============================= Deserialize ignore null\n"); - DeserializeIgnoreNull.Run(); + //Console.WriteLine("\n============================= Deserialize ignore null\n"); + //DeserializeIgnoreNull.Run(); - Console.WriteLine("\n============================= Deserialize trailing commas and comments\n"); - DeserializeCommasComments.Run(); + //Console.WriteLine("\n============================= Deserialize trailing commas and comments\n"); + //DeserializeCommasComments.Run(); - Console.WriteLine("\n============================= Custom converter registration - Converters collection\n"); - RegisterConverterWithConverterscollection.Run(); + //Console.WriteLine("\n============================= Custom converter registration - Converters collection\n"); + //RegisterConverterWithConverterscollection.Run(); - Console.WriteLine("\n============================= Custom converter registration - Converters attribute on property\n"); - RegisterConverterWithAttributeOnProperty.Run(); + //Console.WriteLine("\n============================= Custom converter registration - Converters attribute on property\n"); + //RegisterConverterWithAttributeOnProperty.Run(); - Console.WriteLine("\n============================= Custom converter registration - attribute on type\n"); - RegisterConverterWithAttributeOnType.Run(); + //Console.WriteLine("\n============================= Custom converter registration - attribute on type\n"); + //RegisterConverterWithAttributeOnType.Run(); - Console.WriteLine("\n============================= Custom converter Dictionary with TKey = Enum\n"); - RoundtripDictionaryTkeyEnumTValue.Run(); + //Console.WriteLine("\n============================= Custom converter Dictionary with TKey = Enum\n"); + //RoundtripDictionaryTkeyEnumTValue.Run(); - Console.WriteLine("\n============================= Custom converter Polymorphic\n"); - RoundtripPolymorphic.Run(); + //Console.WriteLine("\n============================= Custom converter Polymorphic\n"); + //RoundtripPolymorphic.Run(); - Console.WriteLine("\n============================= Custom converter inferred types to Object\n"); - DeserializeInferredTypesToObject.Run(); + //Console.WriteLine("\n============================= Custom converter inferred types to Object\n"); + //DeserializeInferredTypesToObject.Run(); - Console.WriteLine("\n============================= Custom converter long to string\n"); - RoundtripLongToString.Run(); + //Console.WriteLine("\n============================= Custom converter long to string\n"); + //RoundtripLongToString.Run(); - Console.WriteLine("\n============================= Callbacks\n"); - RoundtripCallbacks.Run(); + //Console.WriteLine("\n============================= Callbacks\n"); + //RoundtripCallbacks.Run(); - Console.WriteLine("\n============================= Required property converter\n"); - DeserializeRequiredProperty.Run(); + //Console.WriteLine("\n============================= Required property converter\n"); + //DeserializeRequiredProperty.Run(); - Console.WriteLine("\n============================= Required property converter using attribute registration\n"); - DeserializeRequiredPropertyUsingAttributeRegistration.Run(); + //Console.WriteLine("\n============================= Required property converter using attribute registration\n"); + //DeserializeRequiredPropertyUsingAttributeRegistration.Run(); - Console.WriteLine("\n============================= Null value to nonnullable type\n"); - DeserializeNullToNonnullableType.Run(); + //Console.WriteLine("\n============================= Null value to nonnullable type\n"); + //DeserializeNullToNonnullableType.Run(); - Console.WriteLine("\n============================= Immutable struct\n"); - RoundtripImmutableStruct.Run(); + //Console.WriteLine("\n============================= Immutable struct\n"); + //RoundtripImmutableStruct.Run(); - Console.WriteLine("\n============================= Runtime property exclusion\n"); - SerializeRuntimePropertyExclusion.Run(); + //Console.WriteLine("\n============================= Runtime property exclusion\n"); + //SerializeRuntimePropertyExclusion.Run(); Console.WriteLine("\n============================= JsonDocument data access\n"); JsonDocumentDataAccess.Run(); - Console.WriteLine("\n============================= JsonDocument write JSON\n"); - JsonDocumentWriteJson.Run(); + //Console.WriteLine("\n============================= JsonDocument write JSON\n"); + //JsonDocumentWriteJson.Run(); - Console.WriteLine("\n============================= Utf8Reader from file\n"); - Utf8ReaderFromFile.Run(); + //Console.WriteLine("\n============================= Utf8Reader from file\n"); + //Utf8ReaderFromFile.Run(); - string jsonString = File.ReadAllText("Universities.json"); - ValueTextEqualsExample.Run(Encoding.UTF8.GetBytes(jsonString)); + //string jsonString = File.ReadAllText("Universities.json"); + //ValueTextEqualsExample.Run(Encoding.UTF8.GetBytes(jsonString)); - Console.WriteLine("\n============================= Utf8Reader from byte array\n"); - Utf8ReaderFromBytes.Run(); + //Console.WriteLine("\n============================= Utf8Reader from byte array\n"); + //Utf8ReaderFromBytes.Run(); - Console.WriteLine("\n============================= Utf8Reader partial read\n"); - Utf8ReaderPartialRead.Run(); + //Console.WriteLine("\n============================= Utf8Reader partial read\n"); + //Utf8ReaderPartialRead.Run(); - Console.WriteLine("\n============================= Utf8Writer to Stream\n"); - Utf8WriterToStream.Run(); + //Console.WriteLine("\n============================= Utf8Writer to Stream\n"); + //Utf8WriterToStream.Run(); - Console.WriteLine("\n============================= Roundtrip to DataTable\n"); - RoundtripDataTable.Program.Main(); + //Console.WriteLine("\n============================= Roundtrip to DataTable\n"); + //RoundtripDataTable.Program.Main(); } } diff --git a/docs/standard/serialization/system-text-json/snippets/how-to/csharp/SystemTextJsonSamples.csproj b/docs/standard/serialization/system-text-json/snippets/how-to/csharp/SystemTextJsonSamples.csproj index 1ed515a2596e1..949c73306cbca 100644 --- a/docs/standard/serialization/system-text-json/snippets/how-to/csharp/SystemTextJsonSamples.csproj +++ b/docs/standard/serialization/system-text-json/snippets/how-to/csharp/SystemTextJsonSamples.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 SystemTextJsonSamples.Program enable enable diff --git a/docs/standard/serialization/system-text-json/snippets/source-generation/csharp/JsonSerializerOptionsExample.cs b/docs/standard/serialization/system-text-json/snippets/source-generation/csharp/JsonSerializerOptionsExample.cs index ea935213b6a17..0b782ed6680b3 100644 --- a/docs/standard/serialization/system-text-json/snippets/source-generation/csharp/JsonSerializerOptionsExample.cs +++ b/docs/standard/serialization/system-text-json/snippets/source-generation/csharp/JsonSerializerOptionsExample.cs @@ -33,10 +33,10 @@ public static void Main() // weatherForecast = JsonSerializer.Deserialize( - jsonString, - typeof(WeatherForecast), + jsonString, + typeof(WeatherForecast), new OptionsExampleContext( - new JsonSerializerOptions(JsonSerializerDefaults.Web))) + JsonSerializerOptions.Web)) as WeatherForecast; // Console.WriteLine($"Date={weatherForecast?.Date}"); @@ -48,7 +48,7 @@ public static void Main() weatherForecast, typeof(WeatherForecast), new OptionsExampleContext( - new JsonSerializerOptions(JsonSerializerDefaults.Web))); + JsonSerializerOptions.Web)); // Console.WriteLine(jsonString); // output: diff --git a/docs/standard/serialization/system-text-json/snippets/source-generation/csharp/SystemTextJsonSamples.csproj b/docs/standard/serialization/system-text-json/snippets/source-generation/csharp/SystemTextJsonSamples.csproj index 5ac2db608ee85..30b36c1058177 100644 --- a/docs/standard/serialization/system-text-json/snippets/source-generation/csharp/SystemTextJsonSamples.csproj +++ b/docs/standard/serialization/system-text-json/snippets/source-generation/csharp/SystemTextJsonSamples.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 SystemTextJsonSamples.Program enable enable diff --git a/docs/standard/serialization/system-text-json/snippets/use-dom-utf8jsonreader-utf8jsonwriter/csharp/Program.cs b/docs/standard/serialization/system-text-json/snippets/use-dom-utf8jsonreader-utf8jsonwriter/csharp/Program.cs index 9873df41c3bd6..ce82ef0b1cadc 100644 --- a/docs/standard/serialization/system-text-json/snippets/use-dom-utf8jsonreader-utf8jsonwriter/csharp/Program.cs +++ b/docs/standard/serialization/system-text-json/snippets/use-dom-utf8jsonreader-utf8jsonwriter/csharp/Program.cs @@ -1,22 +1,9 @@ -namespace SystemTextJsonSamples; - -public class Program -{ - static void Main() - { - Console.WriteLine("\n============================= JsonNodeWithJsonSerializerOptions example\n"); - JsonNodeWithJsonSerializerOptions.Program.Main(); - Console.WriteLine("\n============================= JsonDocumentWithJsonSerializerOptions example\n"); - JsonDocumentWithJsonSerializerOptions.Program.Main(); - Console.WriteLine("\n============================= From string example\n"); - JsonNodeFromStringExample.Program.Main(); - Console.WriteLine("\n============================= From object example\n"); - JsonNodeFromObjectExample.Program.Main(); - Console.WriteLine("\n============================= POCO example\n"); - JsonNodePOCOExample.Program.Main(); - Console.WriteLine("\n============================= Average Grades example\n"); - JsonNodeAverageGradeExample.Program.Main(); - Console.WriteLine("\n============================= Write raw JSON\n"); - WriteRawJson.Program.Main(); - } -} +//JsonNodeWithJsonSerializerOptions.Program.Main(); +//JsonDocumentWithJsonSerializerOptions.Program.Main(); +//JsonNodeFromStringExample.Program.Main(); +//JsonNodeFromObjectExample.Program.Main(); +//JsonNodePOCOExample.Program.Main(); +//JsonNodeAverageGradeExample.Program.Main(); +//WriteRawJson.Program.Main(); +//ReadMultipleDocs.Program.Main2(); +ReadMultipleDocs.Program.Main3(); diff --git a/docs/standard/serialization/system-text-json/snippets/use-dom-utf8jsonreader-utf8jsonwriter/csharp/ReadMultipleDocs.cs b/docs/standard/serialization/system-text-json/snippets/use-dom-utf8jsonreader-utf8jsonwriter/csharp/ReadMultipleDocs.cs new file mode 100644 index 0000000000000..76804f10cf3e7 --- /dev/null +++ b/docs/standard/serialization/system-text-json/snippets/use-dom-utf8jsonreader-utf8jsonwriter/csharp/ReadMultipleDocs.cs @@ -0,0 +1,65 @@ +using System.Text.Json; + +namespace ReadMultipleDocs; + +public class Program +{ + public static void Main() + { + // + JsonReaderOptions options = new() { AllowMultipleValues = true }; + Utf8JsonReader reader = new("null {} 1 \r\n [1,2,3]"u8, options); + + reader.Read(); + Console.WriteLine(reader.TokenType); // Null + + reader.Read(); + Console.WriteLine(reader.TokenType); // StartObject + reader.Skip(); + + reader.Read(); + Console.WriteLine(reader.TokenType); // Number + + reader.Read(); + Console.WriteLine(reader.TokenType); // StartArray + reader.Skip(); + + Console.WriteLine(reader.Read()); // False + // + } + + public static void Main2() + { + // + JsonReaderOptions options = new() { AllowMultipleValues = true }; + Utf8JsonReader reader = new("[1,2,3] "u8, options); + + reader.Read(); + reader.Skip(); // Succeeds. + reader.Read(); // Throws JsonReaderException. + // + } + + public static async void Main3() + { + // + ReadOnlySpan utf8Json = """[0] [0,1] [0,1,1] [0,1,1,2] [0,1,1,2,3]"""u8; + using var stream = new MemoryStream(utf8Json.ToArray()); + + var items = JsonSerializer.DeserializeAsyncEnumerable(stream, topLevelValues: true); + await foreach (int[] item in items) + { + Console.WriteLine(item.Length); + } + + /* This snippet produces the following output: + * + * 1 + * 2 + * 3 + * 4 + * 5 + */ + // + } +} diff --git a/docs/standard/serialization/system-text-json/snippets/use-dom-utf8jsonreader-utf8jsonwriter/csharp/SystemTextJsonSamples.csproj b/docs/standard/serialization/system-text-json/snippets/use-dom-utf8jsonreader-utf8jsonwriter/csharp/SystemTextJsonSamples.csproj index 7e25878e6c073..2a82780af1bc6 100644 --- a/docs/standard/serialization/system-text-json/snippets/use-dom-utf8jsonreader-utf8jsonwriter/csharp/SystemTextJsonSamples.csproj +++ b/docs/standard/serialization/system-text-json/snippets/use-dom-utf8jsonreader-utf8jsonwriter/csharp/SystemTextJsonSamples.csproj @@ -2,8 +2,8 @@ Exe - net8.0 - SystemTextJsonSamples.Program + net9.0 + enable enable diff --git a/docs/standard/serialization/system-text-json/use-dom.md b/docs/standard/serialization/system-text-json/use-dom.md index b9a95fd912e3d..d42cfc28912aa 100644 --- a/docs/standard/serialization/system-text-json/use-dom.md +++ b/docs/standard/serialization/system-text-json/use-dom.md @@ -85,6 +85,10 @@ The following example illustrates the result of using methods that take a `JsonS If you need features of `JsonSerializerOptions` other than custom converters, use `JsonSerializer` with strongly typed targets (such as the `Person` class in this example) rather than `JsonNode`. +### Compare JsonNodes + +To compare two `JsonNode` objects for equality, including their descendant elements, use the method. + ## Use `JsonDocument` The following example shows how to use the class for random access to data in a JSON string: @@ -117,6 +121,12 @@ Searches on `JsonElement` require a sequential search of the properties and henc * Use the built-in enumerators ( and ) rather than doing your own indexing or loops. * Don't do a sequential search on the whole `JsonDocument` through every property by using `RootElement`. Instead, search on nested JSON objects based on the known structure of the JSON data. For example, the preceding code examples look for a `Grade` property in `Student` objects by looping through the `Student` objects and getting the value of `Grade` for each, rather than searching through all `JsonElement` objects looking for `Grade` properties. Doing the latter would result in unnecessary passes over the same data. +### Compare JsonElements + +To compare two `JsonElement` objects for equality, including their descendant elements, use the method. + +:::code language="csharp" source="snippets/how-to/csharp/JsonDocumentDataAccess.cs" id="DeepEquals"::: + ### Use `JsonDocument` to write JSON The following example shows how to write JSON from a : diff --git a/docs/standard/serialization/system-text-json/use-utf8jsonreader.md b/docs/standard/serialization/system-text-json/use-utf8jsonreader.md index 0e1a2c6214696..2bc3320e40840 100644 --- a/docs/standard/serialization/system-text-json/use-utf8jsonreader.md +++ b/docs/standard/serialization/system-text-json/use-utf8jsonreader.md @@ -13,16 +13,15 @@ ms.topic: how-to This article shows how you can use the type for building custom parsers and deserializers. - is a high-performance, low allocation, forward-only reader for UTF-8 encoded JSON text, read from a `ReadOnlySpan` or `ReadOnlySequence`. The `Utf8JsonReader` is a low-level type that can be used to build custom parsers and deserializers. The methods use `Utf8JsonReader` under the covers. + is a high-performance, low allocation, forward-only reader for UTF-8 encoded JSON text. The text is read from a `ReadOnlySpan` or `ReadOnlySequence`. `Utf8JsonReader` is a low-level type that can be used to build custom parsers and deserializers. (The methods use `Utf8JsonReader` under the covers.) -> `Utf8JsonReader` can't be used directly from Visual Basic code. For more information, see [Visual Basic support](visual-basic-support.md). - -The following example shows how to use the class: +The following example shows how to use the class. This code assumes that the `jsonUtf8Bytes` variable is a byte array that contains valid JSON, encoded as UTF-8. :::code language="csharp" source="snippets/how-to/csharp/Utf8ReaderFromBytes.cs" id="Deserialize"::: :::code language="vb" source="snippets/how-to/vb/Utf8ReaderFromBytes.vb" id="Deserialize"::: -The preceding code assumes that the `jsonUtf8Bytes` variable is a byte array that contains valid JSON, encoded as UTF-8. +> [!NOTE] +> `Utf8JsonReader` can't be used directly from Visual Basic code. For more information, see [Visual Basic support](visual-basic-support.md). ## Filter data using `Utf8JsonReader` @@ -31,13 +30,13 @@ The following example shows how to synchronously read a file and search for a va :::code language="csharp" source="snippets/how-to/csharp/Utf8ReaderFromFile.cs"::: :::code language="vb" source="snippets/how-to/vb/Utf8ReaderFromFile.vb"::: -For an asynchronous version of this example, see [.NET samples JSON project](https://github.com/dotnet/samples/blob/18e31a5f1abd4f347bf96bfdc3e40e2cfb36e319/core/json/Program.cs). - The preceding code: -* Assumes the JSON contains an array of objects and each object might contain a "name" property of type string. +* Assumes the JSON contains an array of objects, and each object might contain a "name" property of type string. * Counts objects and "name" property values that end with "University". -* Assumes the file is encoded as UTF-16 and transcodes it into UTF-8. A file encoded as UTF-8 can be read directly into a `ReadOnlySpan` by using the following code: +* Assumes the file is encoded as UTF-16 and transcodes it into UTF-8. + + A file encoded as UTF-8 can be read directly into a `ReadOnlySpan` by using the following code: ```csharp ReadOnlySpan jsonReadOnlySpan = File.ReadAllBytes(fileName); @@ -49,9 +48,12 @@ Here's a JSON sample that the preceding code can read. The resulting summary mes :::code language="json" source="snippets/how-to/csharp/Universities.json"::: +> [!TIP] +> For an asynchronous version of this example, see [.NET samples JSON project](https://github.com/dotnet/samples/blob/18e31a5f1abd4f347bf96bfdc3e40e2cfb36e319/core/json/Program.cs). + ## Read from a stream using `Utf8JsonReader` -When reading a large file (a gigabyte or more in size, for example), you might want to avoid having to load the entire file into memory at once. For this scenario, you can use a . +When reading a large file (a gigabyte or more in size, for example), you might want to avoid loading the entire file into memory at once. For this scenario, you can use a . When using the `Utf8JsonReader` to read from a stream, the following rules apply: @@ -61,7 +63,7 @@ When using the `Utf8JsonReader` to read from a stream, the following rules apply The following code illustrates how to read from a stream. The example shows a . Similar code will work with a , except when the `FileStream` contains a UTF-8 BOM at the start. In that case, you need to strip those three bytes from the buffer before passing the remaining bytes to the `Utf8JsonReader`. Otherwise the reader would throw an exception, since the BOM is not considered a valid part of the JSON. -The sample code starts with a 4 KB buffer and doubles the buffer size each time it finds that the size is not large enough to fit a complete JSON token, which is required for the reader to make forward progress on the JSON payload. The JSON sample provided in the snippet triggers a buffer size increase only if you set a very small initial buffer size, for example, 10 bytes. If you set the initial buffer size to 10, the `Console.WriteLine` statements illustrate the cause and effect of buffer size increases. At the 4 KB initial buffer size, the entire sample JSON is shown by each `Console.WriteLine`, and the buffer size never has to be increased. +The sample code starts with a 4 KB buffer and doubles the buffer size each time it finds that the size is not large enough to fit a complete JSON token, which is required for the reader to make forward progress on the JSON payload. The JSON sample provided in the snippet triggers a buffer size increase only if you set a very small initial buffer size, for example, 10 bytes. If you set the initial buffer size to 10, the `Console.WriteLine` statements illustrate the cause and effect of buffer size increases. At the 4 KB initial buffer size, the entire sample JSON is shown by each call to `Console.WriteLine`, and the buffer size never has to be increased. :::code language="csharp" source="snippets/how-to/csharp/Utf8ReaderPartialRead.cs"::: :::code language="vb" source="snippets/how-to/vb/Utf8ReaderPartialRead.vb"::: @@ -70,9 +72,9 @@ The preceding example sets no limit to how large the buffer can grow. If the tok ## ref struct limitations -Because the `Utf8JsonReader` type is a *ref struct*, it has [certain limitations](../../../csharp/language-reference/builtin-types/ref-struct.md). For example, it can't be stored as a field on a class or struct other than a ref struct. +Because the `Utf8JsonReader` type is a `ref struct`, it has [certain limitations](../../../csharp/language-reference/builtin-types/ref-struct.md). For example, it can't be stored as a field on a class or struct other than a `ref struct`. -To achieve high performance, this type must be a `ref struct` since it needs to cache the input [ReadOnlySpan\](xref:System.ReadOnlySpan%601), which itself is a ref struct. In addition, the `Utf8JsonReader` type is mutable since it holds state. Therefore, **pass it by reference** rather than by value. Passing it by value would result in a struct copy and the state changes would not be visible to the caller. +To achieve high performance, `Utf8JsonReader` must be a `ref struct`, because it needs to cache the input [ReadOnlySpan\](xref:System.ReadOnlySpan%601) (which itself is a `ref struct`). In addition, the `Utf8JsonReader` type is mutable since it holds state. Therefore, **pass it by reference** rather than by value. Passing the `Utf8JsonReader` by value would result in a struct copy, and the state changes wouldn't be visible to the caller. For more information about how to use ref structs, see [Avoid allocations](../../../csharp/advanced-topics/performance/index.md). @@ -98,9 +100,23 @@ while (reader.Read()) } ``` -## Use ValueTextEquals for property name lookups +## Read multiple JSON documents + +In .NET 9 and later versions, you can read multiple, white space–separated JSON documents from a single buffer or stream. By default, `Utf8JsonReader` throws an exception if it detects any non-white-space characters that trail the first top-level document. However, you can configure that behavior using the flag. + +:::code language="csharp" source="snippets/use-dom-utf8jsonreader-utf8jsonwriter/csharp/ReadMultipleDocs.cs" id="Snippet1"::: + +When is set to `true`, you can also read JSON from payloads that contain trailing data that's invalid JSON. + +:::code language="csharp" source="snippets/use-dom-utf8jsonreader-utf8jsonwriter/csharp/ReadMultipleDocs.cs" id="Snippet2"::: + +To stream multiple top-level values, use the or overload. By default, `DeserializeAsyncEnumerable` attempts to stream elements that are contained in a single, top-level JSON array. Pass `true` for the `topLevelValues` parameter to stream multiple top-level values. + +:::code language="csharp" source="snippets/use-dom-utf8jsonreader-utf8jsonwriter/csharp/ReadMultipleDocs.cs" id="Snippet3"::: + +## Property name lookups -Don't use to do byte-by-byte comparisons by calling for property name lookups. Call instead, because that method unescapes any characters that are escaped in the JSON. Here's an example that shows how to search for a property that's named "name": +To look up property names, don't use to do byte-by-byte comparisons by calling . Instead, call , because this method unescapes any characters that are escaped in the JSON. Here's an example that shows how to search for a property that's named "name": :::code language="csharp" source="snippets/how-to/csharp/ValueTextEqualsExample.cs" id="DefineUtf8Var"::: @@ -160,7 +176,7 @@ Starting in .NET 7, you can use the and the classes that derive from it provide the ability to create a mutable DOM. You can convert a `Utf8JsonReader` instance to a `JsonNode` by calling . The following code snippet shows an example. - :::code language="csharp" source="snippets/how-to/csharp/Utf8ReaderToJsonNode.cs"::: + :::code language="csharp" source="snippets/how-to/csharp/Utf8ReaderToJsonNode.cs"::: * provides the ability to build a read-only DOM by using `Utf8JsonReader`. Call the method to parse a `JsonDocument` from a `Utf8JsonReader` instance. You can access the JSON elements that compose the payload via the type. For example code that uses , see [RoundtripDataTable.cs](https://github.com/dotnet/docs/blob/main/docs/standard/serialization/system-text-json/snippets/how-to/csharp/RoundtripDataTable.cs) and the code snippet in [Deserialize inferred types to object properties](converters-how-to.md#deserialize-inferred-types-to-object-properties). diff --git a/docs/standard/serialization/system-text-json/visual-basic-support.md b/docs/standard/serialization/system-text-json/visual-basic-support.md index aa37063551a8c..31f802a5f7e33 100644 --- a/docs/standard/serialization/system-text-json/visual-basic-support.md +++ b/docs/standard/serialization/system-text-json/visual-basic-support.md @@ -7,9 +7,9 @@ no-loc: [System.Text.Json, Newtonsoft.Json] # Visual Basic support -Parts of System.Text.Json use [ref structs](../../../csharp/language-reference/builtin-types/ref-struct.md), which are not supported by Visual Basic. If you try to use System.Text.Json ref struct APIs with Visual Basic you get BC40000 compiler errors. The error message indicates that the problem is an obsolete API, but the actual issue is lack of ref struct support in the compiler. The following parts of System.Text.Json aren't usable from Visual Basic: +Parts of use [ref structs](../../../csharp/language-reference/builtin-types/ref-struct.md), which are not supported by Visual Basic. If you try to use System.Text.Json ref struct APIs with Visual Basic, you get BC40000 compiler errors. The error message indicates that the problem is an obsolete API, but the actual issue is lack of ref struct support in the compiler. The following parts of System.Text.Json aren't usable from Visual Basic: * The struct. Since the method takes a `Utf8JsonReader` parameter, this limitation means you can't use Visual Basic to write custom converters. A workaround for this is to implement custom converters in a C# library assembly, and reference that assembly from your VB project. This assumes that all you do in Visual Basic is register the converters into the serializer. You can't call the `Read` methods of the converters from Visual Basic code. * Overloads of other APIs that include a type. Most methods include overloads that use `String` instead of `ReadOnlySpan`. -These restrictions are in place because ref structs cannot be used safely without language support, even when just "passing data through." Subverting this error will result in Visual Basic code that can corrupt memory and should not be done. +These restrictions are in place because ref structs cannot be used safely without language support, even when just "passing data through." You should not subvert this error. If you do, your Visual Basic code can corrupt memory.