diff --git a/docs/fundamentals/toc.yml b/docs/fundamentals/toc.yml index 177c87837a13b..300f2a5224c2d 100644 --- a/docs/fundamentals/toc.yml +++ b/docs/fundamentals/toc.yml @@ -2008,6 +2008,8 @@ items: - name: Overview href: ../standard/serialization/system-text-json-overview.md displayName: json serialization + - name: Reflection vs. source generation + href: ../standard/serialization/system-text-json-source-generation-modes.md - name: How to serialize and deserialize JSON href: ../standard/serialization/system-text-json-how-to.md - name: Control serialization behavior @@ -2040,7 +2042,7 @@ items: items: - name: Customize character encoding href: ../standard/serialization/system-text-json-character-encoding.md - - name: Source generation in System.Text.Json + - name: Use source generation href: ../standard/serialization/system-text-json-source-generation.md - name: Write custom converters href: ../standard/serialization/system-text-json-converters-how-to.md diff --git a/docs/standard/serialization/system-text-json-overview.md b/docs/standard/serialization/system-text-json-overview.md index 08dc204253b74..697333261bb7b 100644 --- a/docs/standard/serialization/system-text-json-overview.md +++ b/docs/standard/serialization/system-text-json-overview.md @@ -1,7 +1,7 @@ --- title: "Serialize and deserialize JSON using C# - .NET" description: This overview describes the System.Text.Json namespace functionality for serializing to and deserializing from JSON in .NET. -ms.date: 07/21/2021 +ms.date: 10/18/2021 no-loc: [System.Text.Json, Newtonsoft.Json] zone_pivot_groups: dotnet-version helpviewer_keywords: @@ -21,14 +21,20 @@ The library also provides classes for working with an in-memory document object There are some limitations on what parts of the library that you can use from Visual Basic code. For more information, see [Visual Basic support](system-text-json-how-to.md#visual-basic-support). +## Run-time reflection vs. compile-time source generation + +By default, `System.Text.Json` uses run-time [reflection](../../csharp/programming-guide/concepts/reflection.md) to gather the metadata it needs to access properties of objects for serialization and deserialization. As an alternative, `System.Text.Json` can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and facilitate [assembly trimming](../../core/deploying/trimming/trim-self-contained.md), which reduces app size. For more information, see [How to choose reflection or source generation in System.Text.Json](system-text-json-source-generation-modes.md). + ## How to get the library -* The library is built-in as part of the shared framework for .NET Core 3.0 and later versions. -* For earlier framework versions, install the [System.Text.Json](https://www.nuget.org/packages/System.Text.Json) NuGet package. The package supports: +The library is built-in as part of the shared framework for .NET Core 3.0 and later versions. The source generation feature is built-in as part of the shared framework for .NET 6.0 and later versions. Use of source generation requires .NET 5 SDK or later. + +For framework versions earlier than .NET Core 3.0, install the [System.Text.Json](https://www.nuget.org/packages/System.Text.Json) NuGet package. The package supports: - * .NET Standard 2.0 and later versions - * .NET Framework 4.7.2 and later versions - * .NET Core 2.0, 2.1, and 2.2 +* .NET Standard 2.0 and later +* .NET Framework 4.7.2 and later +* .NET Core 2.1 and later +* .NET 5 and later ## Security information diff --git a/docs/standard/serialization/system-text-json-source-generation-modes.md b/docs/standard/serialization/system-text-json-source-generation-modes.md new file mode 100644 index 0000000000000..35d0a52e0ed43 --- /dev/null +++ b/docs/standard/serialization/system-text-json-source-generation-modes.md @@ -0,0 +1,152 @@ +--- +title: How to choose reflection or source generation in System.Text.Json +description: "Learn how to choose reflection or source generation in System.Text.Json." +ms.date: 10/18/2021 +no-loc: [System.Text.Json] +zone_pivot_groups: dotnet-version +helpviewer_keywords: + - "JSON serialization" + - "serializing objects" + - "serialization" + - "objects, serializing" +ms.topic: how-to +--- + +# How to choose reflection or source generation in System.Text.Json + +:::zone pivot="dotnet-6-0" +> [!IMPORTANT] +> Some information relates to prerelease product that may be substantially modified before it's released. Microsoft makes no warranties, express or implied, with respect to the information provided here. + +By default, `System.Text.Json` uses run-time reflection to gather the metadata it needs to access properties of objects for serialization and deserialization. As an alternative, `System.Text.Json` 6.0 can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and facilitate [assembly trimming](../../core/deploying/trimming/trim-self-contained.md), which reduces app size. + +You can use version 6.0 of System.Text.Json in projects that target earlier frameworks. For more information, see [How to get the library](system-text-json-overview.md#how-to-get-the-library). + +This article explains the options and provides guidance on how to choose the best approach for your scenario. +:::zone-end + +:::zone pivot="dotnet-5-0,dotnet-core-3-1" +[System.Text.Json](system-text-json-overview.md) version 6.0 and later can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and improve [assembly trimming](../../core/deploying/trimming/trim-self-contained.md) accuracy. You can use version 6.0 of System.Text.Json in projects that target earlier frameworks. For more information, see: + +* [How to get the library](system-text-json-overview.md#how-to-get-the-library) +* [The .NET 6.0 version of this article](system-text-json-source-generation-modes.md?pivots=dotnet-6-0). + +:::zone-end + +:::zone pivot="dotnet-6-0" + +## Overview + +Choose reflection or source generation modes based on the following benefits that each one offers: + +| Benefit | Reflection | Source generation:
Metadata collection | Source generation:
Serialization optimization | +|------------------------------------------------------|------------|---------------------|----------------------------| +| Simpler to code and debug. | ✔️ | ❌ | ❌ | +| Supports non-public accessors. | ✔️ | ❌ | ❌ | +| Supports init-only properties. | ✔️ | ❌ | ❌ | +| Supports all available serialization customizations. | ✔️ | ❌ | ❌ | +| Reduces start-up time. | ❌ | ✔️ | ❌ | +| Reduces private memory usage. | ❌ | ✔️ | ✔️ | +| Eliminates run-time reflection. | ❌ | ✔️ | ✔️ | +| Facilitates trim-safe app size reduction. | ❌ | ✔️ | ✔️ | +| Increases serialization throughput. | ❌ | ❌ | ✔️ | + +The following sections explain these options and their relative benefits. + +## System.Text.Json metadata + +To serialize or deserialize a type, needs information about how to access the members of the type. `JsonSerializer` needs the following information: + +* How to access property getters and fields for serialization. +* How to access a constructor, property setters, and fields for deserialization. +* Information about which attributes have been used to customize serialization or deserialization. +* Run-time configuration from . + +This information is referred to as *metadata*. + +By default, `JsonSerializer` collects metadata at run time by using [reflection](../../csharp/programming-guide/concepts/reflection.md). Whenever `JsonSerializer` has to serialize or deserialize a type for the first time, it collects and caches this metadata. The metadata collection process takes time and uses memory. + +## Source generation - metadata collection mode + +You can use source generation to move the metadata collection process from run time to compile time. During compilation, the metadata is collected and source code files are generated. The generated source code files are automatically compiled as an integral part of the application. This compile-time metadata collection eliminates run-time metadata collection, which improves performance of both serialization and deserialization. + +The performance improvements provided by source generation can be substantial. For example, [test results](https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-source-generator/#how-source-generation-provides-benefits) have shown up to 40% or more startup time reduction, private memory reduction, throughput speed increase (in serialization optimization mode), and app size reduction. + +## Source generation - known issues + +Reflection mode supports the use of non-public accessors of public properties. For example, you can apply [[JsonInclude]](xref:System.Text.Json.Serialization.JsonIncludeAttribute) to a property that has a `private` setter or getter. Source generation mode supports only public or internal accessors of public properties. Use of `[JsonInclude]` on non-public accessors in source generation mode results in a `NotSupportedException` at run time. + +Reflection mode also supports deserialization to init-only properties. Source generation doesn't support this, because the metadata-only mode required for deserialization can't express the required initialization statically in source code. The reflection serializer uses run-time reflection to set properties after construction. + +In both reflection and source generation modes: + +* Only public properties and public fields are supported. +* Only public constructors can be used for deserialization. + +For information about the outstanding request to add support for non-public members, see GitHub issue [dotnet/runtime#31511](https://github.com/dotnet/runtime/issues/31511). Even if that request is implemented, source generation mode will still be limited to support for public members. + +For information about other known issues with source generation, see the [GitHub issues that are labeled "source-generator"](https://github.com/dotnet/runtime/issues?q=is%3Aopen+is%3Aissue+label%3Aarea-System.Text.Json+label%3Asource-generator) in the *dotnet/runtime* repository. + +## Serialization optimization mode + +`JsonSerializer` has many features that customize the output of serialization, such as [camel-casing property names](system-text-json-customize-properties.md#use-camel-case-for-all-json-property-names) and [preserving references](system-text-json-preserve-references.md#preserve-references-and-handle-circular-references). Support for all those features causes some performance overhead. Source generation can improve serialization performance by generating optimized code that uses [`Utf8JsonWriter`](system-text-json-use-dom-utf8jsonreader-utf8jsonwriter.md#use-utf8jsonwriter) directly. + +The optimized code doesn't support all of the serialization features that `JsonSerializer` supports. The serializer detects whether the optimized code can be used and falls back to default serialization code if unsupported options are specified. For example, is not applicable to writing, so specifying this option doesn't cause a fall-back to default code. + +The following table shows which options in `JsonSerializerOptions` are supported by the optimized serialization code: + +| Serialization option | Supported by optimized code | +|------------------------------------------------------------------------|-----------------------------| +| | ❌ | +| | ✔️ | +| | ❌ | +| | ❌ | +| | ❌ | +| | ✔️ | +| | ✔️ | +| | ✔️ | +| | ❌ | +| | ✔️ | +| | ❌ | +| | ✔️ | + +The following table shows which attributes are supported by the optimized serialization code: + +| Attribute | Supported by optimized code | +|-------------------------------------------------------------------|-----------------------------| +| | ❌ | +| | ❌ | +| | ✔️ | +| | ✔️ | +| | ❌ | +| | ✔️ | + +If a non-supported option or attribute is specified for a type, the serializer falls back to the default `JsonSerializer` code. In that case, the optimized code isn't used when serializing that type but may be used for other types. Therefore it's important to do performance testing with your options and workloads to determine how much benefit you can actually get from serialization optimization mode. Also, the ability to fall back to `JsonSerializer` code requires metadata collection mode. If you select only serialization optimization mode, serialization might fail for types or options that need to fall back to `JsonSerializer` code. + +## How to use source generation modes + +Most of the System.Text.Json documentation shows how to write code that uses reflection mode. For information about how to use source generation modes, see [How to use source generation in System.Text.Json](system-text-json-source-generation.md). +:::zone-end + +## See also + +* [Try the new System.Text.Json source generator](https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-source-generator/) +* [JSON serialization and deserialization in .NET - overview](system-text-json-overview.md) +* [How to use the library](system-text-json-how-to.md) +* [Instantiate JsonSerializerOptions instances](system-text-json-configure-options.md) +* [Enable case-insensitive matching](system-text-json-character-casing.md) +* [Customize property names and values](system-text-json-customize-properties.md) +* [Ignore properties](system-text-json-ignore-properties.md) +* [Allow invalid JSON](system-text-json-invalid-json.md) +* [Handle overflow JSON or use JsonElement or JsonNode](system-text-json-handle-overflow.md) +* [Preserve references and handle circular references](system-text-json-preserve-references.md) +* [Deserialize to immutable types and non-public accessors](system-text-json-immutability.md) +* [Polymorphic serialization](system-text-json-polymorphism.md) +* [Migrate from Newtonsoft.Json to System.Text.Json](system-text-json-migrate-from-newtonsoft-how-to.md) +* [Customize character encoding](system-text-json-character-encoding.md) +* [Use DOM, Utf8JsonReader, and Utf8JsonWriter](system-text-json-use-dom-utf8jsonreader-utf8jsonwriter.md) +* [Write custom converters for JSON serialization](system-text-json-converters-how-to.md) +* [DateTime and DateTimeOffset support](../datetime/system-text-json-support.md) +* [Supported collection types in System.Text.Json](system-text-json-supported-collection-types.md) +* [System.Text.Json API reference](xref:System.Text.Json) +* [System.Text.Json.Serialization API reference](xref:System.Text.Json.Serialization) diff --git a/docs/standard/serialization/system-text-json-source-generation.md b/docs/standard/serialization/system-text-json-source-generation.md index d698b6a43975f..d37fe152e09fe 100644 --- a/docs/standard/serialization/system-text-json-source-generation.md +++ b/docs/standard/serialization/system-text-json-source-generation.md @@ -21,96 +21,16 @@ ms.topic: how-to > [!IMPORTANT] > Some information relates to prerelease product that may be substantially modified before it's released. Microsoft makes no warranties, express or implied, with respect to the information provided here. -[System.Text.Json](system-text-json-overview.md) can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and facilitate [assembly trimming](../../core/deploying/trimming/trim-self-contained.md), which reduces app size. This article shows how to use the source generation features of System.Text.Json. +This article shows how to use the source generation features of [System.Text.Json](system-text-json-overview.md). :::zone-end :::zone pivot="dotnet-5-0,dotnet-core-3-1" -[System.Text.Json](system-text-json-overview.md) version 6.0 and later can use the C# [source generation](../../csharp/roslyn-sdk/source-generators-overview.md) feature to improve performance, reduce private memory usage, and improve [assembly trimming](../../core/deploying/trimming/trim-self-contained.md) accuracy. For information about how to use source generation in System.Text.Json, see [the .NET 6.0 version of this article](system-text-json-source-generation.md?pivots=dotnet-6-0). +For information about how to use source generation in System.Text.Json, see [the .NET 6.0 version of this article](system-text-json-source-generation.md?pivots=dotnet-6-0). :::zone-end :::zone pivot="dotnet-6-0" -## Source generation modes - -System.Text.Json provides two modes of source generation: - -* Metadata collection -* Serialization optimization - -You can use either mode by itself or in combination. - -### Metadata collection mode - -To serialize or deserialize a type, needs information about how to access the members of the type. To serialize, `JsonSerializer` needs to know how to access property getters and fields. To deserialize, it needs to know how to access a constructor, property setters, and fields. It also needs to know if any attributes have been used to customize serialization or deserialization. This information is referred to as *metadata*. Metadata also includes run-time configuration from . - -By default, `JsonSerializer` collects metadata at run time by using [Reflection](../../csharp/programming-guide/concepts/reflection.md). Whenever `JsonSerializer` has to serialize or deserialize a type for the first time, it collects and caches this metadata. The metadata collection process takes time and uses memory. - -You can use source generation to move the metadata collection process from run time to compile time. During compilation, the metadata is collected and source code files are generated. The generated source code files are automatically compiled as an integral part of the application. This compile-time metadata collection eliminates run-time metadata collection, which improves performance of both serialization and deserialization. - -### Serialization optimization mode - -`JsonSerializer` has many features that customize the output of serialization, such as [camel-casing property names](system-text-json-customize-properties.md#use-camel-case-for-all-json-property-names) and [preserving references](system-text-json-preserve-references.md#preserve-references-and-handle-circular-references). Support for all those features causes some performance overhead. Source generation can improve serialization performance by generating optimized code that uses [`Utf8JsonWriter`](system-text-json-use-dom-utf8jsonreader-utf8jsonwriter.md#use-utf8jsonwriter) directly. The optimized code doesn't support all of the serialization features that `JsonSerializer` supports. The serializer detects whether the optimized code can be used. For example, is not applicable to writing, so this option doesn't prevent the serializer from using the optimized code. - -The following table shows which options specified by `JsonSerializerOptions` are supported by the optimized serialization code: - -| Serialization option | Supported by optimized code | -|------------------------------------------------------------------------|-----------------------------| -| | ❌ | -| | ✔️ | -| | ❌ | -| | ❌ | -| | ❌ | -| | ✔️ | -| | ✔️ | -| | ✔️ | -| | ❌ | -| | ✔️ | -| | ❌ | -| | ✔️ | - -The following table shows which attributes are supported by the optimized serialization code: - -| Attribute | Supported by optimized code | -|-------------------------------------------------------------------|-----------------------------| -| | ❌ | -| | ❌ | -| | ✔️ | -| | ✔️ | -| | ❌ | -| | ✔️ | - -If a non-supported option or attribute is specified for a type, the serializer falls back to the default `JsonSerializer` code. In that case the optimized code isn't used when serializing that type but may be used for other types. - -### Choose a source generation mode - -Choose one or both source generation modes based on the following benefits that each one offers: - -| Benefit | Metadata collection | Serialization optimization | -|-------------------------------------------|---------------------|----------------------------| -| Reduces start-up time. | ✔️ | ❌ | -| Reduces private memory usage. | ✔️ | ✔️ | -| Eliminates run-time reflection. | ✔️ | ✔️ | -| Facilitates trim-safe app size reduction. | ✔️ | ✔️ | -| Increases serialization throughput. | ❌ | ✔️ \* | - -The performance improvements can be substantial. For example, [test results](https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-source-generator/#how-source-generation-provides-benefits) have shown up to 40% or more startup time reduction, private memory reduction, throughput speed increase, and app size reduction. - -\* As explained in the [preceding section](#serialization-optimization-mode), the optimized code doesn't support some features. Do performance testing with your options and workloads to determine how much benefit you can actually get from serialization optimization mode. Also, the ability to fall back to `JsonSerializer` code requires metadata collection mode. If you select only serialization optimization mode, serialization might fail for types or options that need to fall back to `JsonSerializer` code. - -## Get the source generation functionality - -The source generation functionality for System.Text.Json can be used in any .NET C# project, including class libraries and console, web, and Blazor applications. It can be used with .NET 5.0 SDK or later and with the following target frameworks: - -* .NET Core 2.1 and later -* .NET 5 and later -* .NET Framework 4.7.2 and later -* .NET Standard 2.0 and later - -For projects that target .NET 6 or later, there's no need to install the [System.Text.Json NuGet package](https://www.nuget.org/packages/System.Text.Json) because source generation is included in the runtime. - -For other target frameworks, install the latest preview version of the package. - -## Use source generation +## Use source generation defaults To use source generation with all defaults (both modes, default options): @@ -219,7 +139,7 @@ Here are the preceding examples in a complete program: ## Specify options by using `JsonSerializerOptions` -Some options of aren't supported by serialization optimization mode. Such options cause a fallback to the non-source-generated `JsonSerializer` code. For more information, see [Serialization optimization](#serialization-optimization-mode). +Some options of aren't supported by serialization optimization mode. Such options cause a fallback to the non-source-generated `JsonSerializer` code. For more information, see [Serialization optimization](system-text-json-source-generation-modes.md#serialization-optimization-mode). To specify options by using :