Skip to content

Commit eeecda4

Browse files
authored
New article - Migrate from Newtonsoft.Json (#16225)
1 parent a3d2fa0 commit eeecda4

File tree

7 files changed

+745
-59
lines changed

7 files changed

+745
-59
lines changed

docs/framework/wcf/feature-details/stand-alone-json-serialization.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ ms.assetid: 312bd7b2-1300-4b12-801e-ebe742bd2287
66
# Stand-Alone JSON Serialization using DataContractJsonSerializer
77

88
> [!NOTE]
9-
> This article is about <xref:System.Runtime.Serialization.Json.DataContractJsonSerializer>. For most scenarios that involve serializing and deserializing JSON, we recommend the tools in the [System.Text.Json namespace](../../../standard/serialization/system-text-json-overview.md).
9+
> This article is about <xref:System.Runtime.Serialization.Json.DataContractJsonSerializer>. For most scenarios that involve serializing and deserializing JSON, we recommend the APIs in the [System.Text.Json namespace](../../../standard/serialization/system-text-json-overview.md).
1010
1111
JSON (JavaScript Object Notation) is a data format that is specifically designed to be used by JavaScript code running on Web pages inside the browser. It is the default data format used by ASP.NET AJAX services created in Windows Communication Foundation (WCF).
1212

docs/framework/wcf/samples/json-serialization.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ ms.assetid: 3c2c4747-7510-4bdf-b4fe-64f98428ef4a
66
# DataContractJsonSerializer sample
77

88
> [!NOTE]
9-
> This sample is for <xref:System.Runtime.Serialization.Json.DataContractJsonSerializer>. For most scenarios that involve serializing and deserializing JSON, we recommend the tools in the [System.Text.Json namespace](../../../standard/serialization/system-text-json-overview.md).
9+
> This sample is for <xref:System.Runtime.Serialization.Json.DataContractJsonSerializer>. For most scenarios that involve serializing and deserializing JSON, we recommend the APIs in the [System.Text.Json namespace](../../../standard/serialization/system-text-json-overview.md).
1010
1111
<xref:System.Runtime.Serialization.Json.DataContractJsonSerializer> supports the same types as <xref:System.Runtime.Serialization.DataContractSerializer>. The JSON data format is especially useful when writing Asynchronous JavaScript and XML (AJAX)-style Web applications. AJAX support in Windows Communication Foundation (WCF) is optimized for use with ASP.NET AJAX through the ScriptManager control. For examples of how to use Windows Communication Foundation (WCF) with ASP.NET AJAX, see the [AJAX Samples](ajax.md).
1212

docs/standard/serialization/system-text-json-converters-how-to.md

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "How to write custom converters for JSON serialization - .NET"
3-
ms.date: "10/16/2019"
3+
ms.date: "01/10/2020"
44
helpviewer_keywords:
55
- "JSON serialization"
66
- "serializing objects"
@@ -9,7 +9,7 @@ helpviewer_keywords:
99
- "converters"
1010
---
1111

12-
# How to write custom converters for JSON serialization in .NET
12+
# How to write custom converters for JSON serialization (marshalling) in .NET
1313

1414
This article shows how to create custom converters for the JSON serialization classes that are provided in the <xref:System.Text.Json> namespace. For an introduction to `System.Text.Json`, see [How to serialize and deserialize JSON in .NET](system-text-json-how-to.md).
1515

@@ -18,9 +18,9 @@ A *converter* is a class that converts an object or a value to and from JSON. Th
1818
* To override the default behavior of a built-in converter. For example, you might want `DateTime` values to be represented by mm/dd/yyyy format instead of the default ISO 8601-1:2019 format.
1919
* To support a custom value type. For example, a `PhoneNumber` struct.
2020

21-
You can also write custom converters to extend `System.Text.Json` with functionality not included in the current release. The following scenarios are covered later in this article:
21+
You can also write custom converters to customize or extend `System.Text.Json` with functionality not included in the current release. The following scenarios are covered later in this article:
2222

23-
* [Deserialize inferred types to Object properties](#deserialize-inferred-types-to-object-properties).
23+
* [Deserialize inferred types to object properties](#deserialize-inferred-types-to-object-properties).
2424
* [Support Dictionary with non-string key](#support-dictionary-with-non-string-key).
2525
* [Support polymorphic deserialization](#support-polymorphic-deserialization).
2626

@@ -63,9 +63,9 @@ The following steps explain how to create a converter by following the basic pat
6363
* Create a class that derives from <xref:System.Text.Json.Serialization.JsonConverter%601> where `T` is the type to be serialized and deserialized.
6464
* Override the `Read` method to deserialize the incoming JSON and convert it to type `T`. Use the <xref:System.Text.Json.Utf8JsonReader> that is passed to the method to read the JSON.
6565
* Override the `Write` method to serialize the incoming object of type `T`. Use the <xref:System.Text.Json.Utf8JsonWriter> that is passed to the method to write the JSON.
66-
* Override the `CanConvert` method only if necessary. The default implementation returns `true` when the type to convert is type `T`. Therefore, converters that support only type `T` don't need to override this method. For an example of a converter that does need to override this method, see the [polymorphic deserialization](#support-polymorphic-deserialization) section later in this article.
66+
* Override the `CanConvert` method only if necessary. The default implementation returns `true` when the type to convert is of type `T`. Therefore, converters that support only type `T` don't need to override this method. For an example of a converter that does need to override this method, see the [polymorphic deserialization](#support-polymorphic-deserialization) section later in this article.
6767

68-
You can refer to the [built-in converters source code](https://github.com/dotnet/corefx/tree/master/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/) as reference implementations for writing custom converters.
68+
You can refer to the [built-in converters source code](https://github.com/dotnet/runtime/tree/81bf79fd9aa75305e55abe2f7e9ef3f60624a3a1/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/) as reference implementations for writing custom converters.
6969

7070
## Steps to follow the factory pattern
7171

@@ -168,20 +168,21 @@ A built-in converter is chosen only if no applicable custom converter is registe
168168

169169
The following sections provide converter samples that address some common scenarios that built-in functionality doesn't handle.
170170

171-
* [Deserialize inferred types to Object properties](#deserialize-inferred-types-to-object-properties)
171+
* [Deserialize inferred types to object properties](#deserialize-inferred-types-to-object-properties)
172172
* [Support Dictionary with non-string key](#support-dictionary-with-non-string-key)
173173
* [Support polymorphic deserialization](#support-polymorphic-deserialization)
174174

175-
### Deserialize inferred types to Object properties
175+
### Deserialize inferred types to object properties
176176

177-
When deserializing to a property of type `Object`, a `JsonElement` object is created. The reason is that the deserializer doesn't know what CLR type to create, and it doesn't try to guess. For example, if a JSON property has "true", the deserializer doesn't infer that the value is a `Boolean`, and if an element has "01/01/2019", the deserializer doesn't infer that it's a `DateTime`.
177+
When deserializing to a property of type `object`, a `JsonElement` object is created. The reason is that the deserializer doesn't know what CLR type to create, and it doesn't try to guess. For example, if a JSON property has "true", the deserializer doesn't infer that the value is a `Boolean`, and if an element has "01/01/2019", the deserializer doesn't infer that it's a `DateTime`.
178178

179179
Type inference can be inaccurate. If the deserializer parses a JSON number that has no decimal point as a `long`, that might result in out-of-range issues if the value was originally serialized as a `ulong` or `BigInteger`. Parsing a number that has a decimal point as a `double` might lose precision if the number was originally serialized as a `decimal`.
180180

181-
For scenarios that require type inference, the following code shows a custom converter for `Object` properties. The code converts:
181+
For scenarios that require type inference, the following code shows a custom converter for `object` properties. The code converts:
182182

183183
* `true` and `false` to `Boolean`
184-
* Numbers to `long` or `double`
184+
* Numbers without a decimal to `long`
185+
* Numbers with a decimal to `double`
185186
* Dates to `DateTime`
186187
* Strings to `string`
187188
* Everything else to `JsonElement`
@@ -190,9 +191,9 @@ For scenarios that require type inference, the following code shows a custom con
190191

191192
The following code registers the converter:
192193

193-
[!code-csharp[](~/samples/snippets/core/system-text-json/csharp/ConvertInferredTypesToObject.cs?name=SnippetRegister)]
194+
[!code-csharp[](~/samples/snippets/core/system-text-json/csharp/DeserializeInferredTypesToObject.cs?name=SnippetRegister)]
194195

195-
Here's an example type with `Object` properties:
196+
Here's an example type with `object` properties:
196197

197198
[!code-csharp[](~/samples/snippets/core/system-text-json/csharp/WeatherForecast.cs?name=SnippetWFWithObjectProperties)]
198199

@@ -208,7 +209,7 @@ The following example of JSON to deserialize contains values that will be deseri
208209

209210
Without the custom converter, deserialization puts a `JsonElement` in each property.
210211

211-
The [unit tests folder](https://github.com/dotnet/corefx/blob/master/src/System.Text.Json/tests/Serialization/) in the `System.Text.Json.Serialization` namespace has more examples of custom converters that handle deserialization to Object properties.
212+
The [unit tests folder](https://github.com/dotnet/runtime/blob/81bf79fd9aa75305e55abe2f7e9ef3f60624a3a1/src/libraries/System.Text.Json/tests/Serialization/) in the `System.Text.Json.Serialization` namespace has more examples of custom converters that handle deserialization to `object` properties.
212213

213214
### Support Dictionary with non-string key
214215

@@ -220,7 +221,7 @@ The following code shows a custom converter that works with `Dictionary<Enum,TVa
220221

221222
The following code registers the converter:
222223

223-
[!code-csharp[](~/samples/snippets/core/system-text-json/csharp/ConvertDictionaryTkeyEnumTValue.cs?name=SnippetRegister)]
224+
[!code-csharp[](~/samples/snippets/core/system-text-json/csharp/RoundtripDictionaryTkeyEnumTValue.cs?name=SnippetRegister)]
224225

225226
The converter can serialize and deserialize the `TemperatureRanges` property of the following class that uses the following `Enum`:
226227

@@ -240,11 +241,11 @@ The JSON output from serialization looks like the following example:
240241
}
241242
```
242243

243-
The [unit tests folder](https://github.com/dotnet/corefx/blob/master/src/System.Text.Json/tests/Serialization/) in the `System.Text.Json.Serialization` namespace has more examples of custom converters that handle non-string-key dictionaries.
244+
The [unit tests folder](https://github.com/dotnet/runtime/blob/81bf79fd9aa75305e55abe2f7e9ef3f60624a3a1/src/libraries/System.Text.Json/tests/Serialization/) in the `System.Text.Json.Serialization` namespace has more examples of custom converters that handle non-string-key dictionaries.
244245

245246
### Support polymorphic deserialization
246247

247-
[Polymorphic serialization](system-text-json-how-to.md#serialize-properties-of-derived-classes) doesn't require a custom converter, but deserialization does require a custom converter.
248+
Built-in features provide a limited range of [polymorphic serialization](system-text-json-how-to.md#serialize-properties-of-derived-classes) but no support for deserialization at all. Deserialization requires a custom converter.
248249

249250
Suppose, for example, you have a `Person` abstract base class, with `Employee` and `Customer` derived classes. Polymorphic deserialization means that at design time you can specify `Person` as the deserialization target, and `Customer` and `Employee` objects in the JSON are correctly deserialized at runtime. During deserialization, you have to find clues that identify the required type in the JSON. The kinds of clues available vary with each scenario. For example, a discriminator property might be available or you might have to rely on the presence or absence of a particular property. The current release of `System.Text.Json` doesn't provide attributes to specify how to handle polymorphic deserialization scenarios, so custom converters are required.
250251

@@ -256,7 +257,7 @@ The following code shows a base class, two derived classes, and a custom convert
256257

257258
The following code registers the converter:
258259

259-
[!code-csharp[](~/samples/snippets/core/system-text-json/csharp/ConvertPolymorphic.cs?name=SnippetRegister)]
260+
[!code-csharp[](~/samples/snippets/core/system-text-json/csharp/RoundtripPolymorphic.cs?name=SnippetRegister)]
260261

261262
The converter can deserialize JSON that was created by using the same converter to serialize, for example:
262263

@@ -277,22 +278,25 @@ The converter can deserialize JSON that was created by using the same converter
277278

278279
## Other custom converter samples
279280

280-
The [unit tests folder](https://github.com/dotnet/corefx/blob/master/src/System.Text.Json/tests/Serialization/) in the `System.Text.Json.Serialization` source code includes other custom converter samples, such as:
281+
The [Migrate from Newtonsoft.Json to System.Text.Json](system-text-json-migrate-from-newtonsoft-how-to.md) article contains additional samples of custom converters.
281282

282-
* `Int32` converter that converts null to 0 on deserialize
283-
* `Int32` converter that allows both string and number values on deserialize
284-
* `Enum` converter
285-
* `List<T>` converter that accepts external data
286-
* `Long[]` converter that works with a comma-delimited list of numbers
283+
The [unit tests folder](https://github.com/dotnet/runtime/blob/81bf79fd9aa75305e55abe2f7e9ef3f60624a3a1/src/libraries/System.Text.Json/tests/Serialization/) in the `System.Text.Json.Serialization` source code includes other custom converter samples, such as:
284+
285+
* [Int32 converter that converts null to 0 on deserialize](https://github.com/dotnet/runtime/blob/81bf79fd9aa75305e55abe2f7e9ef3f60624a3a1/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.NullValueType.cs)
286+
* [Int32 converter that allows both string and number values on deserialize](https://github.com/dotnet/runtime/blob/81bf79fd9aa75305e55abe2f7e9ef3f60624a3a1/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.Int32.cs)
287+
* [Enum converter](https://github.com/dotnet/runtime/blob/81bf79fd9aa75305e55abe2f7e9ef3f60624a3a1/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.Enum.cs)
288+
* [List\<T> converter that accepts external data](https://github.com/dotnet/runtime/blob/81bf79fd9aa75305e55abe2f7e9ef3f60624a3a1/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.List.cs)
289+
* [Long[] converter that works with a comma-delimited list of numbers](https://github.com/dotnet/runtime/blob/81bf79fd9aa75305e55abe2f7e9ef3f60624a3a1/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.Array.cs)
290+
291+
If you need to make a converter that modifies the behavior of an existing built-in converter, you can get [the source code of the existing converter](https://github.com/dotnet/runtime/tree/81bf79fd9aa75305e55abe2f7e9ef3f60624a3a1/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters) to serve as a starting point for customization.
287292

288293
## Additional resources
289294

295+
* [Source code for built-in converters](https://github.com/dotnet/runtime/tree/81bf79fd9aa75305e55abe2f7e9ef3f60624a3a1/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters)
296+
* [DateTime and DateTimeOffset support in System.Text.Json](../datetime/system-text-json-support.md)
290297
* [System.Text.Json overview](system-text-json-overview.md)
291-
* [System.Text.Json API reference](xref:System.Text.Json)
292298
* [How to use System.Text.Json](system-text-json-how-to.md)
293-
* [Source code for built-in converters](https://github.com/dotnet/corefx/tree/master/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/)
294-
* GitHub issues related to custom converters for `System.Text.Json`
295-
* [36639 Introducing custom converters](https://github.com/dotnet/corefx/issues/36639)
296-
* [38713 About deserializing to Object](https://github.com/dotnet/corefx/issues/38713)
297-
* [40120 About non-string-key dictionaries](https://github.com/dotnet/corefx/issues/40120)
298-
* [37787 About polymorphic deserialization](https://github.com/dotnet/corefx/issues/37787)
299+
* [How to migrate from Newtonsoft.Json](system-text-json-migrate-from-newtonsoft-how-to.md)
300+
* [System.Text.Json API reference](xref:System.Text.Json)
301+
* [System.Text.Json.Serialization API reference](xref:System.Text.Json.Serialization)
302+
<!-- * [System.Text.Json roadmap](https://github.com/dotnet/runtime/blob/81bf79fd9aa75305e55abe2f7e9ef3f60624a3a1/src/libraries/System.Text.Json/roadmap/README.md)-->

0 commit comments

Comments
 (0)