You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# Stand-Alone JSON Serialization using DataContractJsonSerializer
7
7
8
8
> [!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).
10
10
11
11
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).
> 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).
10
10
11
11
<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).
Copy file name to clipboardExpand all lines: docs/standard/serialization/system-text-json-converters-how-to.md
+35-31Lines changed: 35 additions & 31 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
---
2
2
title: "How to write custom converters for JSON serialization - .NET"
3
-
ms.date: "10/16/2019"
3
+
ms.date: "01/10/2020"
4
4
helpviewer_keywords:
5
5
- "JSON serialization"
6
6
- "serializing objects"
@@ -9,7 +9,7 @@ helpviewer_keywords:
9
9
- "converters"
10
10
---
11
11
12
-
# How to write custom converters for JSON serialization in .NET
12
+
# How to write custom converters for JSON serialization (marshalling) in .NET
13
13
14
14
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).
15
15
@@ -18,9 +18,9 @@ A *converter* is a class that converts an object or a value to and from JSON. Th
18
18
* 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.
19
19
* To support a custom value type. For example, a `PhoneNumber` struct.
20
20
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:
22
22
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).
24
24
*[Support Dictionary with non-string key](#support-dictionary-with-non-string-key).
@@ -63,9 +63,9 @@ The following steps explain how to create a converter by following the basic pat
63
63
* Create a class that derives from <xref:System.Text.Json.Serialization.JsonConverter%601> where `T` is the type to be serialized and deserialized.
64
64
* 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.
65
65
* 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.
67
67
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.
69
69
70
70
## Steps to follow the factory pattern
71
71
@@ -168,20 +168,21 @@ A built-in converter is chosen only if no applicable custom converter is registe
168
168
169
169
The following sections provide converter samples that address some common scenarios that built-in functionality doesn't handle.
170
170
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)
172
172
*[Support Dictionary with non-string key](#support-dictionary-with-non-string-key)
### Deserialize inferred types to Object properties
175
+
### Deserialize inferred types to object properties
176
176
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`.
178
178
179
179
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`.
180
180
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:
182
182
183
183
*`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`
185
186
* Dates to `DateTime`
186
187
* Strings to `string`
187
188
* Everything else to `JsonElement`
@@ -190,9 +191,9 @@ For scenarios that require type inference, the following code shows a custom con
@@ -208,7 +209,7 @@ The following example of JSON to deserialize contains values that will be deseri
208
209
209
210
Without the custom converter, deserialization puts a `JsonElement` in each property.
210
211
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.
212
213
213
214
### Support Dictionary with non-string key
214
215
@@ -220,7 +221,7 @@ The following code shows a custom converter that works with `Dictionary<Enum,TVa
The converter can serialize and deserialize the `TemperatureRanges` property of the following class that uses the following `Enum`:
226
227
@@ -240,11 +241,11 @@ The JSON output from serialization looks like the following example:
240
241
}
241
242
```
242
243
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.
244
245
245
246
### Support polymorphic deserialization
246
247
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.
248
249
249
250
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.
250
251
@@ -256,7 +257,7 @@ The following code shows a base class, two derived classes, and a custom convert
The converter can deserialize JSON that was created by using the same converter to serialize, for example:
262
263
@@ -277,22 +278,25 @@ The converter can deserialize JSON that was created by using the same converter
277
278
278
279
## Other custom converter samples
279
280
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.
281
282
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)
*[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.
287
292
288
293
## Additional resources
289
294
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)
*[System.Text.Json API reference](xref:System.Text.Json)
292
298
*[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`
0 commit comments