Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/fundamentals/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,8 @@ items:
href: ../standard/serialization/system-text-json/converters-how-to.md
- 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
- name: XML and SOAP serialization
items:
- name: Overview
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ ms.topic: how-to

# How to enable case-insensitive property name matching with System.Text.Json

In this article, you will learn how to enable case-insensitive property name matching with the `System.Text.Json` namespace.
In this article, you learn how to enable case-insensitive property name matching with the `System.Text.Json` namespace.

## Case-insensitive property matching

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ By default, the serializer escapes all non-ASCII characters. That is, it replace

## Serialize language character sets

To serialize the character set(s) of one or more languages without escaping, specify [Unicode range(s)](xref:System.Text.Unicode.UnicodeRanges) when creating an instance of <xref:System.Text.Encodings.Web.JavaScriptEncoder?displayProperty=fullName>, as shown in the following example:
To serialize the character sets of one or more languages without escaping, specify [Unicode ranges](xref:System.Text.Unicode.UnicodeRanges) when creating an instance of <xref:System.Text.Encodings.Web.JavaScriptEncoder?displayProperty=fullName>, as shown in the following example:

:::code language="csharp" source="snippets/how-to/csharp/SerializeCustomEncoding.cs" id="Usings":::
:::code language="vb" source="snippets/how-to/vb/SerializeCustomEncoding.vb" id="Usings":::
Expand Down Expand Up @@ -86,7 +86,7 @@ Examples of encoder-specific blocked code points include `'<'` and `'&'` for the

## Serialize all characters

To minimize escaping you can use <xref:System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping?displayProperty=nameWithType>, as shown in the following example:
To minimize escaping, you can use <xref:System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping?displayProperty=nameWithType>, as shown in the following example:

:::code language="csharp" source="snippets/how-to/csharp/SerializeCustomEncoding.cs" id="Usings":::
:::code language="vb" source="snippets/how-to/vb/SerializeCustomEncoding.vb" id="Usings":::
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ The following options have different defaults for web apps:
* <xref:System.Text.Json.JsonSerializerOptions.PropertyNamingPolicy> = <xref:System.Text.Json.JsonNamingPolicy.CamelCase>
* <xref:System.Text.Json.JsonSerializerOptions.NumberHandling%2A> = <xref:System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString>

In .NET 9 and later versions, you can use the `JsonSerializerOptions.Web` <!-- <xref:System.Text.Json.JsonSerializerOptions.Web?displayProperty=nameWithType> --> singleton to serialize with the default options that ASP.NET Core uses for web apps. In earlier versions, call the [JsonSerializerOptions constructor](xref:System.Text.Json.JsonSerializerOptions.%23ctor(System.Text.Json.JsonSerializerDefaults)) to create a new instance with the web defaults, as shown in the following example:
In .NET 9 and later versions, you can use the <xref:System.Text.Json.JsonSerializerOptions.Web?displayProperty=nameWithType> singleton to serialize with the default options that ASP.NET Core uses for web apps. In earlier versions, call the [JsonSerializerOptions constructor](xref:System.Text.Json.JsonSerializerOptions.%23ctor(System.Text.Json.JsonSerializerDefaults)) to create a new instance with the web defaults, as shown in the following example:

:::code language="csharp" source="snippets/how-to-contd/csharp/OptionsDefaults.cs" highlight="23":::
:::code language="vb" source="snippets/how-to-contd/vb/OptionsDefaults.vb" :::
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ ms.topic: how-to

# How to handle overflow JSON or use JsonElement or JsonNode in System.Text.Json

This article shows how to handle overflow JSON with the [`System.Text.Json`](xref:System.Text.Json) namespace. It also shows how to deserialize into <xref:System.Text.Json.JsonElement> or <xref:System.Text.Json.Nodes.JsonNode>, as an alternative for other scenarios where the target type might not perfectly match all of the JSON being deserialized.
This article shows how to handle overflow JSON with the <xref:System.Text.Json> namespace. It also shows how to deserialize into <xref:System.Text.Json.JsonElement> or <xref:System.Text.Json.Nodes.JsonNode>, as an alternative for other scenarios where the target type might not perfectly match all of the JSON being deserialized.

## Handle overflow JSON

Expand Down Expand Up @@ -51,12 +51,12 @@ If you deserialize the JSON shown into the type shown, the `DatesAvailable` and

The following table shows the result of deserializing the JSON shown earlier into this sample type. The extra data becomes key-value pairs of the `ExtensionData` property:

| Property | Value | Notes |
|--|--|--|
| `Date` | `"8/1/2019 12:00:00 AM -07:00"` | |
| Property | Value | Notes |
|-----------|---------------------------------|-------|
| `Date` | `"8/1/2019 12:00:00 AM -07:00"` | |
| `TemperatureCelsius` | `0` | Case-sensitive mismatch (`temperatureCelsius` in the JSON), so the property isn't set. |
| `Summary` | `"Hot"` | |
| `ExtensionData` | `"temperatureCelsius": 25,`<br>`"DatesAvailable": ["2019-08-01T00:00:00-07:00","2019-08-02T00:00:00-07:00"],`<br>`"SummaryWords": ["Cool","Windy","Humid"]`| Since the case didn't match, `temperatureCelsius` is an extra and becomes a key-value pair in the dictionary. <br>Each extra array from the JSON becomes a key-value pair, with an array as the value object.|
| `Summary` | `"Hot"` | |
| `ExtensionData` | `"temperatureCelsius": 25,`<br>`"DatesAvailable": ["2019-08-01T00:00:00-07:00","2019-08-02T00:00:00-07:00"],`<br>`"SummaryWords": ["Cool","Windy","Humid"]` | Since the case didn't match, `temperatureCelsius` is an extra and becomes a key-value pair in the dictionary. <br>Each extra array from the JSON becomes a key-value pair, with an array as the value object. |

When the target object is serialized, the extension data key value pairs become JSON properties just as they were in the incoming JSON:

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: JSON schema exporter
description: Learn how to use the JsonSchemaExporter class to extract JSON schema documents from .NET types.
ms.date: 10/15/2024
dev_langs:
- "csharp"
---

# JSON schema exporter

The new <xref:System.Text.Json.Schema.JsonSchemaExporter> class lets you extract [JSON schema](https://json-schema.org/) documents from .NET types using either an <xref:System.Text.Json.JsonSerializerOptions> or <xref:System.Text.Json.Serialization.Metadata.JsonTypeInfo> instance. The resultant schema provides a specification of the JSON serialization contract for the type.

The following code snippet shows an example.

:::code language="csharp" source="snippets/schema-exporter/ExportSchema.cs" id="1":::

As can be seen in this example, the exporter distinguishes between nullable and non-nullable properties, and it populates the `required` keyword by virtue of a constructor parameter being optional or not.

## Configure the schema output

You can influence the schema output by configuration specified in the <xref:System.Text.Json.JsonSerializerOptions> or <xref:System.Text.Json.Serialization.Metadata.JsonTypeInfo> instance that you call the <xref:System.Text.Json.Schema.JsonSchemaExporter.GetJsonSchemaAsNode*> method on. The following example sets the naming policy to <xref:System.Text.Json.JsonNamingPolicy.KebabCaseUpper>, writes numbers as strings, and disallows unmapped properties.

:::code language="csharp" source="snippets/schema-exporter/ExportSchema.cs" id="2":::

You can further control the generated schema using the <xref:System.Text.Json.Schema.JsonSchemaExporterOptions> configuration type. The following example sets the <xref:System.Text.Json.Schema.JsonSchemaExporterOptions.TreatNullObliviousAsNonNullable> property to `true` to mark root-level types as non-nullable.

:::code language="csharp" source="snippets/schema-exporter/ExportSchema.cs" id="3":::

## Transform the generated schema

You can apply your own transformations to generated schema nodes by specifying a <xref:System.Text.Json.Schema.JsonSchemaExporterOptions.TransformSchemaNode> delegate. The following example incorporates text from <xref:System.ComponentModel.DescriptionAttribute> annotations into the generated schema.

:::code language="csharp" source="snippets/schema-exporter/TransformSchema.cs" id="1":::

The following code example generates a schema that incorporates `description` keyword source from <xref:System.ComponentModel.DescriptionAttribute> annotations:

:::code language="csharp" source="snippets/schema-exporter/TransformSchema.cs" id="2":::
:::code language="csharp" source="snippets/schema-exporter/TransformSchema.cs" id="Person":::
Original file line number Diff line number Diff line change
Expand Up @@ -29,82 +29,18 @@ The `System.Text.Json` namespace provides functionality for serializing to and d

`System.Text.Json` focuses primarily on performance, security, and standards compliance. It has some key differences in default behavior and doesn't aim to have feature parity with `Newtonsoft.Json`. For some scenarios, `System.Text.Json` currently has no built-in functionality, but there are recommended workarounds. For other scenarios, workarounds are impractical.

We're investing in adding the features that are most often requested. If your application depends on a missing feature, consider [filing an issue](https://github.com/dotnet/runtime/issues/new) in the dotnet/runtime GitHub repository to find out if support for your scenario can be added.
The `System.Text.Json` team is investing in adding the features that are most often requested. If your application depends on a missing feature, consider [filing an issue](https://github.com/dotnet/runtime/issues/new) in the dotnet/runtime GitHub repository to find out if support for your scenario can be added.

Most of this article is about how to use the <xref:System.Text.Json.JsonSerializer> API, but it also includes guidance on how to use the <xref:System.Text.Json.JsonDocument> (which represents the Document Object Model or DOM), <xref:System.Text.Json.Utf8JsonReader>, and <xref:System.Text.Json.Utf8JsonWriter> types.

In Visual Basic, you can't use <xref:System.Text.Json.Utf8JsonReader>, which also means you can't write custom converters. Most of the workarounds presented here require that you write custom converters. You can write a custom converter in C# and register it in a Visual Basic project. For more information, see [Visual Basic support](visual-basic-support.md).

## Use GitHub Copilot to migrate

You can get coding help from GitHub Copilot to convert your code within your IDE.

If you're using [Visual Studio 2022 version 17.8 or later](/visualstudio/releases/2022/release-notes), you can try the AI-driven [GitHub Copilot in Visual Studio](/visualstudio/ide/visual-studio-github-copilot-install-and-states) to help migrate your `Newtonsoft.Json` code to use `System.Text.Json`. Submit your question and the code to convert as a prompt in the copilot chat window, as in the following example.

>[!NOTE]
>GitHub Copilot is powered by AI, so surprises and mistakes are possible. Make sure to verify any generated code or suggestions. For more information about the general use of GitHub Copilot, product impact, human oversight, and privacy, see [GitHub Copilot FAQs](https://github.com/features/copilot#faq).

**Example prompt for Copilot Chat**

```
convert the following code to use System.Text.Json
Product product = new Product();

product.Name = "Apple";
product.ExpiryDate = new DateTime(2024, 08, 08);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };

string output = JsonConvert.SerializeObject(product);
Console.WriteLine(output);
```

**Example Copilot Chat response**

```output
To convert the code to use System.Text.Json, you can use the JsonSerializer class. Here's the updated code:
using System;
using System.Text.Json;

public class Product
{
public string Name { get; set; }
public DateTime ExpiryDate { get; set; }
public decimal Price { get; set; }
public string[] Sizes { get; set; }
}

public class Program
{
public static void Main()
{
Product product = new Product();

product.Name = "Apple";
product.ExpiryDate = new DateTime(2024, 08, 08);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };

string output = JsonSerializer.Serialize(product);
Console.WriteLine(output);
}
}
This code uses System.Text.Json.JsonSerializer.Serialize to convert the Product object to a JSON string.
```

Note that your results might be different from what is shown in these example responses. AI models are non-deterministic, which means that they can return different responses when asked the same question. This might be due to additional learning and adaption over time, language variation, changes in context, such as your chat history, and more.

:::image type="content" source="./media/migrate-newtonsoft-json-using-github-copilot.gif" alt-text="Animated screenshot that shows using GitHub Copilot Chat in Visual Studio to migrate from newtonsoft" lightbox="./media/migrate-newtonsoft-json-using-github-copilot.gif":::

You can use chat features, such as [slash commands, references, and threads](/visualstudio/ide/copilot-chat-context), to set intent and get better answers with scoped context.
For example, if your code file `filename` is open in the IDE, you can [reference the file](/visualstudio/ide/copilot-chat-context#reference-a-file) in your prompt to Copilot Chat with "convert `#filename` to use `System.Text.Json`". Or you can [reference the solution](/visualstudio/ide/copilot-chat-context#reference-the-entire-solution) with "convert `@workspace` to use `System.Text.Json`" in the chat window or in inline chat.

## Table of differences

The following table lists `Newtonsoft.Json` features and `System.Text.Json` equivalents. The equivalents fall into the following categories:

* ✔️ Supported by built-in functionality. Getting similar behavior from `System.Text.Json` may require the use of an attribute or global option.
* ⚠️ Not supported, but workaround is possible. The workarounds are [custom converters](converters-how-to.md), which may not provide complete parity with `Newtonsoft.Json` functionality. For some of these, sample code is provided as examples. If you rely on these `Newtonsoft.Json` features, migration will require modifications to your .NET object models or other code changes.
* ✔️ Supported by built-in functionality. Getting similar behavior from `System.Text.Json` might require the use of an attribute or global option.
* ⚠️ Not supported, but workaround is possible. The workarounds are [custom converters](converters-how-to.md), which might not provide complete parity with `Newtonsoft.Json` functionality. For some of these, sample code is provided as examples. If you rely on these `Newtonsoft.Json` features, migration will require modifications to your .NET object models or other code changes.
* ❌ Not supported, and workaround is not practical or possible. If you rely on these `Newtonsoft.Json` features, migration will not be possible without significant changes.

::: zone pivot="dotnet-9-0, dotnet-8-0"
Expand Down Expand Up @@ -895,6 +831,70 @@ System.Text.Json sets limits that can't be changed for some values, such as the

Newtonsoft parses `NaN`, `Infinity`, and `-Infinity` JSON string tokens. With System.Text.Json, use <xref:System.Text.Json.Serialization.JsonNumberHandling.AllowNamedFloatingPointLiterals?displayProperty=nameWithType>. For information about how to use this setting, see [Allow or write numbers in quotes](invalid-json.md#allow-or-write-numbers-in-quotes).

## Use GitHub Copilot to migrate

You can get coding help from GitHub Copilot to convert your code within your IDE.

If you're using [Visual Studio 2022 version 17.8 or later](/visualstudio/releases/2022/release-notes), you can try the AI-driven [GitHub Copilot in Visual Studio](/visualstudio/ide/visual-studio-github-copilot-install-and-states) to help migrate your `Newtonsoft.Json` code to use `System.Text.Json`. Submit your question and the code to convert as a prompt in the copilot chat window, as in the following example.

> [!NOTE]
> GitHub Copilot is powered by AI, so surprises and mistakes are possible. Make sure to verify any generated code or suggestions. For more information about the general use of GitHub Copilot, product impact, human oversight, and privacy, see [GitHub Copilot FAQs](https://github.com/features/copilot#faq).

**Example prompt for Copilot Chat**

```
convert the following code to use System.Text.Json
Product product = new Product();

product.Name = "Apple";
product.ExpiryDate = new DateTime(2024, 08, 08);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };

string output = JsonConvert.SerializeObject(product);
Console.WriteLine(output);
```

**Example Copilot Chat response**

```output
To convert the code to use System.Text.Json, you can use the JsonSerializer class. Here's the updated code:
using System;
using System.Text.Json;

public class Product
{
public string Name { get; set; }
public DateTime ExpiryDate { get; set; }
public decimal Price { get; set; }
public string[] Sizes { get; set; }
}

public class Program
{
public static void Main()
{
Product product = new Product();

product.Name = "Apple";
product.ExpiryDate = new DateTime(2024, 08, 08);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };

string output = JsonSerializer.Serialize(product);
Console.WriteLine(output);
}
}
This code uses System.Text.Json.JsonSerializer.Serialize to convert the Product object to a JSON string.
```

Note that your results might be different from what is shown in these example responses. AI models are non-deterministic, which means that they can return different responses when asked the same question. This might be due to additional learning and adaption over time, language variation, changes in context, such as your chat history, and more.

:::image type="content" source="./media/migrate-newtonsoft-json-using-github-copilot.gif" alt-text="Animated screenshot that shows using GitHub Copilot Chat in Visual Studio to migrate from newtonsoft" lightbox="./media/migrate-newtonsoft-json-using-github-copilot.gif":::

You can use chat features, such as [slash commands, references, and threads](/visualstudio/ide/copilot-chat-context), to set intent and get better answers with scoped context.
For example, if your code file `filename` is open in the IDE, you can [reference the file](/visualstudio/ide/copilot-chat-context#reference-a-file) in your prompt to Copilot Chat with "convert `#filename` to use `System.Text.Json`". Or you can [reference the solution](/visualstudio/ide/copilot-chat-context#reference-the-entire-solution) with "convert `@workspace` to use `System.Text.Json`" in the chat window or in inline chat.

## Additional resources

* [System.Text.Json overview](overview.md)
Expand Down
Loading
Loading