Partager via


Types pris en charge dans System.Text.Json

Cet article fournit une vue d’ensemble des types pris en charge pour la sérialisation et la désérialisation.

Types sérialisables en tant qu’objets JSON

Les types suivants sérialisent en tant qu’objets JSON :

  • Classes*
  • Structs
  • Interfaces
  • Enregistrements et enregistrements de struct

* Types non-dictionnaire qui implémentent IEnumerable<T> sérialiser en tant que tableaux JSON. Types de dictionnaires, qui implémentent IEnumerable<T>, sérialisent en tant qu’objets JSON.

L’extrait de code suivant montre la sérialisation d’un struct simple.

public static void Main()
{
    var coordinates = new Coords(1.0, 2.0);
    string json = JsonSerializer.Serialize(coordinates);
    Console.WriteLine(json);

    // Output:
    // {"X":1,"Y":2}
}

public readonly struct Coords
{
    public Coords(double x, double y)
    {
        X = x;
        Y = y;
    }

    public double X { get; }
    public double Y { get; }
}

Types sérialisables en tant que tableaux JSON

Les types de collection .NET sérialisent en tant que tableaux JSON. System.Text.Json.JsonSerializer prend en charge un type de collection pour la sérialisation si elle :

Le sérialiseur appelle la méthode GetEnumerator() et écrit les éléments.

La désérialisation est plus compliquée et n’est pas prise en charge pour certains types de collection.

Les sections suivantes sont organisées par espace de noms et indiquent quels types sont pris en charge pour la sérialisation et la désérialisation.

Espace de noms System.Array

Type Sérialisation Désérialisation
tableaux unidimensionnels ✔️ ✔️
tableaux multidimensionnels
tableaux jagged ✔️ ✔️

Espace de noms System.Collections

Type Sérialisation Désérialisation
ArrayList ✔️ ✔️
BitArray ✔️
DictionaryEntry ✔️ ✔️
Hashtable ✔️ ✔️
ICollection ✔️ ✔️
IDictionary ✔️ ✔️
IEnumerable ✔️ ✔️
IList ✔️ ✔️
Queue ✔️ ✔️
SortedList ✔️ ✔️
Stack * ✔️ ✔️

* Consultez Prise en charge des allers-retours pour les types Stack.

Espace de noms System.Collections.Generic

Type Sérialisation Désérialisation
Dictionary<TKey,TValue> * ✔️ ✔️
HashSet<T> ✔️ ✔️
IAsyncEnumerable<T> ✔️ ✔️
ICollection<T> ✔️ ✔️
IDictionary<TKey,TValue> * ✔️ ✔️
IEnumerable<T> ✔️ ✔️
IList<T> ✔️ ✔️
IReadOnlyCollection<T> ✔️ ✔️
IReadOnlyDictionary<TKey,TValue> * ✔️ ✔️
IReadOnlyList<T> ✔️ ✔️
ISet<T> ✔️ ✔️
KeyValuePair<TKey,TValue> ✔️ ✔️
LinkedList<T> ✔️ ✔️
LinkedListNode<T> ✔️
List<T> ✔️ ✔️
Queue<T> ✔️ ✔️
SortedDictionary<TKey,TValue> * ✔️ ✔️
SortedList<TKey,TValue> * ✔️ ✔️
SortedSet<T> ✔️ ✔️
Stack<T> Stack<T> ± ✔️ ✔️

* Consultez types de clés pris en charge.

† Consultez la section suivante sur IAsyncEnumerable<T>.

• Voir Prise en charge des allers-retours pour les types Stack.

IAsyncEnumerable<T>

Les exemples suivants utilisent des flux comme représentation de n’importe quelle source asynchrone de données. La source peut être des fichiers sur une machine locale, ou des résultats à partir d’une requête de base de données ou d’un appel d’API de service web.

Sérialisation de flux

System.Text.Json prend en charge la sérialisation de valeurs IAsyncEnumerable<T> en tant que tableaux JSON, comme illustré dans l’exemple suivant :

using System.Text.Json;

namespace IAsyncEnumerableSerialize;

public class Program
{
    public static async Task Main()
    {
        using Stream stream = Console.OpenStandardOutput();
        var data = new { Data = PrintNumbers(3) };
        await JsonSerializer.SerializeAsync(stream, data);
    }

    static async IAsyncEnumerable<int> PrintNumbers(int n)
    {
        for (int i = 0; i < n; i++)
        {
            await Task.Delay(1000);
            yield return i;
        }
    }
}
// output:
//  {"Data":[0,1,2]}

IAsyncEnumerable<T> valeurs ne sont prises en charge que par les méthodes de sérialisation asynchrones, telles que JsonSerializer.SerializeAsync.

Désérialisation de flux

La méthode DeserializeAsyncEnumerable prend en charge la désérialisation de streaming, comme illustré dans l’exemple suivant :

using System.Text;
using System.Text.Json;

namespace IAsyncEnumerableDeserialize;

public class Program
{
    public static async Task Main()
    {
        using var stream = new MemoryStream(Encoding.UTF8.GetBytes("[0,1,2,3,4]"));
        await foreach (int item in JsonSerializer.DeserializeAsyncEnumerable<int>(stream))
        {
            Console.WriteLine(item);
        }
    }
}
// output:
//0
//1
//2
//3
//4

La méthode DeserializeAsyncEnumerable prend uniquement en charge la lecture à partir de tableaux JSON de niveau racine.

La méthode DeserializeAsync prend en charge IAsyncEnumerable<T>, mais sa signature n’autorise pas la diffusion en continu. Elle retourne le résultat final sous la forme d’une valeur unique, comme illustré dans l’exemple suivant.

using System.Text;
using System.Text.Json;

namespace IAsyncEnumerableDeserializeNonStreaming;

public class MyPoco
{
    public IAsyncEnumerable<int>? Data { get; set; }
}

public class Program
{
    public static async Task Main()
    {
        using var stream = new MemoryStream(Encoding.UTF8.GetBytes(@"{""Data"":[0,1,2,3,4]}"));
        MyPoco? result = await JsonSerializer.DeserializeAsync<MyPoco>(stream)!;
        await foreach (int item in result!.Data!)
        {
            Console.WriteLine(item);
        }
    }
}
// output:
//0
//1
//2
//3
//4

Dans cet exemple, le désérialiseur met en mémoire tampon tout IAsyncEnumerable<T> contenu en mémoire avant de renvoyer l’objet désérialisé. Ce comportement est nécessaire, car le désérialiseur doit lire l’intégralité de la charge utile JSON avant de retourner un résultat.

Espace de noms System.Collections.Immutable

Type Sérialisation Désérialisation
IImmutableDictionary<TKey,TValue> ✔️ ✔️
IImmutableList<T> ✔️ ✔️
IImmutableQueue<T> ✔️ ✔️
IImmutableSet<T> ✔️ ✔️
IImmutableStack<T> * ✔️ ✔️
ImmutableArray<T> ✔️ ✔️
ImmutableDictionary<TKey,TValue> ✔️ ✔️
ImmutableHashSet<T> ✔️ ✔️
ImmutableQueue<T> ✔️ ✔️
ImmutableSortedDictionary<TKey,TValue> ✔️ ✔️
ImmutableSortedSet<T> ✔️ ✔️
ImmutableStack<T> * ✔️ ✔️

* Consultez Prise en charge des allers-retours pour les types Stack.

† Consultez types de clés pris en charge.

Espace de noms System.Collections.Specialized

Type Sérialisation Désérialisation
BitVector32 ✔️ ❌*
HybridDictionary ✔️ ✔️
IOrderedDictionary ✔️
ListDictionary ✔️ ✔️
NameValueCollection ✔️
StringCollection ✔️
StringDictionary ✔️

* Lorsque BitVector32 est désérialisé, la propriété Data est ignorée, car elle n’a pas de setter public. Aucune exception n’est levée.

Espace de noms System.Collections.Concurrent

Type Sérialisation Désérialisation
BlockingCollection<T> ✔️
ConcurrentBag<T> ✔️
ConcurrentDictionary<TKey,TValue> ✔️ ✔️
ConcurrentQueue<T> ✔️ ✔️
ConcurrentStack<T> * ✔️ ✔️

* Consultez Prise en charge des allers-retours pour les types Stack.

† Consultez types de clés pris en charge.

Espace de noms System.Collections.ObjectModel

Type Sérialisation Désérialisation
Collection<T> ✔️ ✔️
chaîne KeyedCollection<, TValue> * ✔️
ObservableCollection<T> ✔️ ✔️
ReadOnlyCollection<T> ✔️
ReadOnlyDictionary<TKey,TValue> ✔️
ReadOnlyObservableCollection<T> ✔️

* Les clés nonstring ne sont pas prises en charge.

Collections personnalisées

Tout type de collection qui n’est pas dans l’un des espaces de noms précédents est considéré comme une collection personnalisée. Ces types incluent les types définis par l’utilisateur et les types définis par ASP.NET Core. Par exemple, Microsoft.Extensions.Primitives se trouve dans ce groupe.

Toutes les collections personnalisées (tout ce qui dérive de IEnumerable) sont prises en charge pour la sérialisation, tant que leurs types d’éléments sont pris en charge.

Prise en charge de la désérialisation

Une collection personnalisée est prise en charge pour la désérialisation si elle :

Problèmes connus

Il existe des problèmes connus avec les collections personnalisées suivantes :

Pour plus d’informations sur les problèmes connus, consultez la les problèmes ouverts dans System.Text.Json.

Types de clés pris en charge

Lorsqu’ils sont utilisés comme clés de Dictionary et de types SortedList, les types suivants prennent en charge les éléments suivants :

  • Boolean
  • Byte
  • DateTime
  • DateTimeOffset
  • Decimal
  • Double
  • Enum
  • Guid
  • Int16
  • Int32
  • Int64
  • Object (uniquement sur la sérialisation et si le type d’exécution est l’un des types pris en charge dans cette liste.)
  • SByte
  • Single
  • String
  • TimeSpan
  • UInt16
  • UInt32
  • UInt64
  • Uri
  • Version

En outre, les méthodes JsonConverter<T>.WriteAsPropertyName(Utf8JsonWriter, T, JsonSerializerOptions) et JsonConverter<T>.ReadAsPropertyName(Utf8JsonReader, Type, JsonSerializerOptions) vous permettent d’ajouter la prise en charge des clés de dictionnaire pour n’importe quel type de votre choix.

Types non pris en charge

Les types suivants ne sont pas pris en charge pour la sérialisation :

Espace de noms System.Data

Il n’existe aucun convertisseur intégré pour DataSet, DataTableet les types associés dans l’espace de noms System.Data. La désérialisation de ces types à partir d’une entrée non approuvée n’est pas sécurisée, comme expliqué dans les instructions de sécurité. Toutefois, vous pouvez écrire un convertisseur personnalisé pour prendre en charge ces types. Pour obtenir un exemple de code de convertisseur personnalisé qui sérialise et désérialise un DataTable, consultez RoundtripDataTable.cs.

Voir aussi