Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New article - Migrate from Newtonsoft.Json #16225

Merged
merged 76 commits into from
Jan 11, 2020
Merged
Show file tree
Hide file tree
Changes from 75 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
db7bdad
initial draft
tdykstra Nov 27, 2019
c9e7a21
fix links
tdykstra Dec 12, 2019
88cd245
fix link
tdykstra Dec 13, 2019
0f60978
corrections
tdykstra Dec 13, 2019
3c634dc
add new doc to toc
tdykstra Dec 13, 2019
d994f56
add'l notes from ahson email
tdykstra Dec 13, 2019
6d4216c
fix issue numbers
tdykstra Dec 13, 2019
2594e49
comment out roadmap link
tdykstra Dec 13, 2019
823b581
incorporate info from roadmap
tdykstra Dec 15, 2019
7dd85d6
more info from roadmap
tdykstra Dec 15, 2019
3a2ab3d
address thraka feedback
tdykstra Dec 17, 2019
c546273
Newtonsoft --> Json.NET
tdykstra Dec 17, 2019
07cc159
omit 'the current release of'
tdykstra Dec 17, 2019
20f1095
omit 'by design'
tdykstra Dec 17, 2019
41019bc
link to exact hash instead of branch
tdykstra Dec 17, 2019
0665118
Json.NET --> Newtonsoft.Json
tdykstra Dec 17, 2019
7243deb
scrub additional resources sections
tdykstra Dec 17, 2019
163ed4e
rearrange several h2 sections
tdykstra Dec 17, 2019
b5bd3e7
add (marshal/unmarshal) to headings
tdykstra Dec 19, 2019
7771245
update dates
tdykstra Dec 20, 2019
a1eae47
ahson feedback, restore code to converters doc
tdykstra Dec 24, 2019
b023d84
move 3 converters back to converter doc
tdykstra Dec 24, 2019
55d99cc
additional note from comments in 36639
tdykstra Dec 24, 2019
a78c5ac
minor clarification
tdykstra Dec 26, 2019
9c331ff
remove links to issues
tdykstra Dec 27, 2019
618aca8
add links to s.t.j.serialization
tdykstra Dec 27, 2019
84a65bc
remove extraneous words
tdykstra Dec 27, 2019
e4a27a1
remove extraneous words
tdykstra Dec 27, 2019
6b279eb
4.6.1 --> 4.7.2
tdykstra Dec 27, 2019
2feef06
Update docs/standard/serialization/system-text-json-converters-how-to.md
tdykstra Dec 27, 2019
99619d1
ahson feedback section 1
tdykstra Dec 27, 2019
ec3d07c
fix h2->h3, tweak heading text
tdykstra Dec 27, 2019
1919f9d
layomi feedback
tdykstra Dec 27, 2019
0f9a494
reapply change lost earlier
tdykstra Dec 27, 2019
16b73b3
remove dbnull comments
tdykstra Dec 28, 2019
4618b0c
Apply suggestions from code review
tdykstra Dec 31, 2019
1bcb4f3
Apply suggestion from code review
tdykstra Dec 31, 2019
66dbd62
ahson feedback
tdykstra Dec 31, 2019
805f425
Merge branch 'jnmigrate' of https://github.com/tdykstra/dotnet-docs i…
tdykstra Dec 31, 2019
6fc6377
make registration links more specific
tdykstra Dec 31, 2019
57fb760
add converters api link
tdykstra Jan 1, 2020
35434dd
Apply suggestions from code review
tdykstra Jan 1, 2020
93d7564
add note to null-to-nonnullable section
tdykstra Jan 1, 2020
2610c4a
Update docs/standard/serialization/system-text-json-migrate-from-newt…
tdykstra Jan 1, 2020
957f976
Apply suggestions from code review
tdykstra Jan 1, 2020
9fc486a
fix link
tdykstra Jan 1, 2020
bc30ca2
acrolinx and feedback
tdykstra Jan 1, 2020
9a057bb
add workaround notes
tdykstra Jan 1, 2020
93194b2
first occurrrences of STJ --> xref link
tdykstra Jan 6, 2020
2273cf4
more api ref links
tdykstra Jan 6, 2020
1c34eb5
Merge branch 'master' into jnmigrate
tdykstra Jan 6, 2020
0890e2e
strings in quotes, nonstring values, polymorphism
tdykstra Jan 7, 2020
5a0b857
corrections to polymorphic sections
tdykstra Jan 7, 2020
b721d7b
address feedback
tdykstra Jan 7, 2020
f6b0a55
more feedback
tdykstra Jan 7, 2020
26930e8
minor wording change
tdykstra Jan 7, 2020
b68ba5e
misc feedback
tdykstra Jan 8, 2020
80ed897
misc feedback
tdykstra Jan 8, 2020
c2191e6
revise polymorphic interface example
tdykstra Jan 8, 2020
43a657a
misc feedback
tdykstra Jan 8, 2020
7b53d91
fix links
tdykstra Jan 8, 2020
fd05648
standardize links to source code
tdykstra Jan 8, 2020
303d8e5
shorten valuetextequals example
tdykstra Jan 8, 2020
63e02ab
misc feedback
tdykstra Jan 8, 2020
65be137
misc feedback
tdykstra Jan 9, 2020
72a8a34
valuetuple
tdykstra Jan 10, 2020
50b3574
invitation to share workaround code
tdykstra Jan 10, 2020
fd61261
feedback
tdykstra Jan 10, 2020
942e7c2
proofread pass
tdykstra Jan 10, 2020
f6d6623
update ms.date
tdykstra Jan 10, 2020
2fa28ee
tools --> APIs
tdykstra Jan 10, 2020
27d4fd4
feedback
tdykstra Jan 10, 2020
55ee7b7
immutablestack
tdykstra Jan 10, 2020
b3eb4f4
clarify when to clone
tdykstra Jan 10, 2020
2470d9e
revert change already made by 16615
tdykstra Jan 11, 2020
30277d7
Update docs/standard/serialization/system-text-json-migrate-from-newt…
tdykstra Jan 11, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ms.assetid: 312bd7b2-1300-4b12-801e-ebe742bd2287
# Stand-Alone JSON Serialization using DataContractJsonSerializer

> [!NOTE]
> 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).
> 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).

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).

Expand Down
2 changes: 1 addition & 1 deletion docs/framework/wcf/samples/json-serialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ms.assetid: 3c2c4747-7510-4bdf-b4fe-64f98428ef4a
# DataContractJsonSerializer sample

> [!NOTE]
> 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).
> 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).

<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).

Expand Down
66 changes: 35 additions & 31 deletions docs/standard/serialization/system-text-json-converters-how-to.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "How to write custom converters for JSON serialization - .NET"
ms.date: "10/16/2019"
ms.date: "01/10/2020"
helpviewer_keywords:
- "JSON serialization"
- "serializing objects"
Expand All @@ -9,7 +9,7 @@ helpviewer_keywords:
- "converters"
---

# How to write custom converters for JSON serialization in .NET
# How to write custom converters for JSON serialization (marshalling) in .NET

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).

Expand All @@ -18,9 +18,9 @@ A *converter* is a class that converts an object or a value to and from JSON. Th
* 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.
* To support a custom value type. For example, a `PhoneNumber` struct.

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:
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:
tdykstra marked this conversation as resolved.
Show resolved Hide resolved

* [Deserialize inferred types to Object properties](#deserialize-inferred-types-to-object-properties).
tdykstra marked this conversation as resolved.
Show resolved Hide resolved
* [Deserialize inferred types to object properties](#deserialize-inferred-types-to-object-properties).
* [Support Dictionary with non-string key](#support-dictionary-with-non-string-key).
* [Support polymorphic deserialization](#support-polymorphic-deserialization).

Expand Down Expand Up @@ -63,9 +63,9 @@ The following steps explain how to create a converter by following the basic pat
* Create a class that derives from <xref:System.Text.Json.Serialization.JsonConverter%601> where `T` is the type to be serialized and deserialized.
* 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.
* 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.
* 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.
* 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.

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.
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.

## Steps to follow the factory pattern

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

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

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

### Deserialize inferred types to Object properties
### Deserialize inferred types to object properties

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`.
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`.

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`.

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

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

The following code registers the converter:

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

Here's an example type with `Object` properties:
Here's an example type with `object` properties:

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

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

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

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.
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.

### Support Dictionary with non-string key

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

The following code registers the converter:

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

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

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

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.
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.

### Support polymorphic deserialization
tdykstra marked this conversation as resolved.
Show resolved Hide resolved

[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.
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.

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.

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

The following code registers the converter:

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

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

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

## Other custom converter samples

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:
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.

* `Int32` converter that converts null to 0 on deserialize
* `Int32` converter that allows both string and number values on deserialize
* `Enum` converter
* `List<T>` converter that accepts external data
* `Long[]` converter that works with a comma-delimited list of numbers
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:

* [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)
* [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)
* [Enum converter](https://github.com/dotnet/runtime/blob/81bf79fd9aa75305e55abe2f7e9ef3f60624a3a1/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.Enum.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)
* [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)

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.

## Additional resources

* [Source code for built-in converters](https://github.com/dotnet/runtime/tree/81bf79fd9aa75305e55abe2f7e9ef3f60624a3a1/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters)
* [DateTime and DateTimeOffset support in System.Text.Json](../datetime/system-text-json-support.md)
* [System.Text.Json overview](system-text-json-overview.md)
* [System.Text.Json API reference](xref:System.Text.Json)
* [How to use System.Text.Json](system-text-json-how-to.md)
* [Source code for built-in converters](https://github.com/dotnet/corefx/tree/master/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/)
* GitHub issues related to custom converters for `System.Text.Json`
* [36639 Introducing custom converters](https://github.com/dotnet/corefx/issues/36639)
* [38713 About deserializing to Object](https://github.com/dotnet/corefx/issues/38713)
* [40120 About non-string-key dictionaries](https://github.com/dotnet/corefx/issues/40120)
* [37787 About polymorphic deserialization](https://github.com/dotnet/corefx/issues/37787)
* [How to migrate from Newtonsoft.Json](system-text-json-migrate-from-newtonsoft-how-to.md)
* [System.Text.Json API reference](xref:System.Text.Json)
tdykstra marked this conversation as resolved.
Show resolved Hide resolved
* [System.Text.Json.Serialization API reference](xref:System.Text.Json.Serialization)
<!-- * [System.Text.Json roadmap](https://github.com/dotnet/runtime/blob/81bf79fd9aa75305e55abe2f7e9ef3f60624a3a1/src/libraries/System.Text.Json/roadmap/README.md)-->
Loading