Condividi tramite


Tipi supportati in System.Text.Json

Questo articolo offre una panoramica dei tipi supportati per la serializzazione e la deserializzazione.

Tipi serializzati come oggetti JSON

I tipi seguenti vengono serializzati come oggetti JSON:

  • * classi
  • Struct
  • Interfacce
  • Record e record struct

* Tipi non di dizionario che implementano IEnumerable<T> serializzare come matrici JSON. Tipi di dizionario, che implementano IEnumerable<T>, serializzare come oggetti JSON.

Il frammento di codice seguente illustra la serializzazione di uno struct semplice.

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; }
}

Tipi serializzati come matrici JSON

I tipi di raccolta .NET vengono serializzati come matrici JSON. System.Text.Json.JsonSerializer supporta un tipo di raccolta per la serializzazione, se:

Il serializzatore chiama il metodo GetEnumerator() e scrive gli elementi.

La deserializzazione è più complessa e non è supportata per alcuni tipi di raccolta.

Le sezioni seguenti sono organizzate in base allo spazio dei nomi e mostrano quali tipi sono supportati per la serializzazione e la deserializzazione.

Spazio dei nomi System.Array

Digitare Serializzazione Deserializzazione
matrici unidimensionali ✔️ ✔️
matrici multidimensionali
matrici frastagliati ✔️ ✔️

Spazio dei nomi System.Collections

Digitare Serializzazione Deserializzazione
ArrayList ✔️ ✔️
BitArray ✔️
DictionaryEntry ✔️ ✔️
Hashtable ✔️ ✔️
ICollection ✔️ ✔️
IDictionary ✔️ ✔️
IEnumerable ✔️ ✔️
IList ✔️ ✔️
Queue ✔️ ✔️
SortedList ✔️ ✔️
Stack * ✔️ ✔️

* Per i tipi di , vedere round trip di supporto .

Spazio dei nomi System.Collections.Generic

Digitare Serializzazione Deserializzazione
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> * ✔️ ✔️

* Vedere tipi di chiave supportati.

† Vedere la sezione seguente in IAsyncEnumerable<T>.

* Vedere round trip supporto per Stack tipi.

IAsyncEnumerable<T>

Negli esempi seguenti vengono usati flussi come rappresentazione di qualsiasi origine dati asincrona. L'origine può essere file in un computer locale o risultati da una query di database o una chiamata API del servizio Web.

Serializzazione dei flussi

System.Text.Json supporta la serializzazione dei valori IAsyncEnumerable<T> come matrici JSON, come illustrato nell'esempio seguente:

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> valori sono supportati solo dai metodi di serializzazione asincroni, ad esempio JsonSerializer.SerializeAsync.

Deserializzazione dei flussi

Il metodo DeserializeAsyncEnumerable supporta la deserializzazione di streaming, come illustrato nell'esempio seguente:

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

Il metodo DeserializeAsyncEnumerable supporta solo la lettura da matrici JSON a livello radice.

Il metodo DeserializeAsync supporta IAsyncEnumerable<T>, ma la firma non consente lo streaming. Restituisce il risultato finale come singolo valore, come illustrato nell'esempio seguente.

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

In questo esempio, il deserializzatore memorizza tutti i IAsyncEnumerable<T> contenuto in memoria prima di restituire l'oggetto deserializzato. Questo comportamento è necessario perché il deserializzatore deve leggere l'intero payload JSON prima di restituire un risultato.

Spazio dei nomi System.Collections.Immutable

Digitare Serializzazione Deserializzazione
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> * ✔️ ✔️

* Per i tipi di , vedere round trip di supporto .

† Vedere Tipi di chiave supportati.

Spazio dei nomi System.Collections.Specialized

Digitare Serializzazione Deserializzazione
BitVector32 ✔️ ❌*
HybridDictionary ✔️ ✔️
IOrderedDictionary ✔️
ListDictionary ✔️ ✔️
NameValueCollection ✔️
StringCollection ✔️
StringDictionary ✔️

* Quando BitVector32 viene deserializzato, la proprietà Data viene ignorata perché non ha un setter pubblico. Non viene generata alcuna eccezione.

Spazio dei nomi System.Collections.Concurrent

Digitare Serializzazione Deserializzazione
BlockingCollection<T> ✔️
ConcurrentBag<T> ✔️
ConcurrentDictionary<TKey,TValue> ✔️ ✔️
ConcurrentQueue<T> ✔️ ✔️
ConcurrentStack<T> * ✔️ ✔️

* Per i tipi di , vedere round trip di supporto .

† Vedere Tipi di chiave supportati.

Spazio dei nomi System.Collections.ObjectModel

Digitare Serializzazione Deserializzazione
Collection<T> ✔️ ✔️
stringa<KeyedCollection,> * TValue ✔️
ObservableCollection<T> ✔️ ✔️
ReadOnlyCollection<T> ✔️
ReadOnlyDictionary<TKey,TValue> ✔️
ReadOnlyObservableCollection<T> ✔️

* Le chiavi nonstring non sono supportate.

Raccolte personalizzate

Qualsiasi tipo di raccolta che non si trova in uno degli spazi dei nomi precedenti viene considerato una raccolta personalizzata. Tali tipi includono tipi e tipi definiti dall'utente definiti da ASP.NET Core. Ad esempio, Microsoft.Extensions.Primitives si trova in questo gruppo.

Tutte le raccolte personalizzate (tutto ciò che deriva da IEnumerable) sono supportate per la serializzazione, purché siano supportati i relativi tipi di elemento.

Supporto della deserializzazione

Una raccolta personalizzata è supportata per la deserializzazione, se:

Problemi noti

Esistono problemi noti con le raccolte personalizzate seguenti:

Per altre informazioni sui problemi noti, vedere i problemi aperti di in System.Text.Json.

Tipi di chiave supportati

Se usato come chiavi di Dictionary e tipi di SortedList, i tipi seguenti hanno il supporto predefinito:

  • Boolean
  • Byte
  • DateTime
  • DateTimeOffset
  • Decimal
  • Double
  • Enum
  • Guid
  • Int16
  • Int32
  • Int64
  • Object (solo in caso di serializzazione e se il tipo di runtime è uno dei tipi supportati in questo elenco).
  • SByte
  • Single
  • String
  • TimeSpan
  • UInt16
  • UInt32
  • UInt64
  • Uri
  • Version

Inoltre, i metodi JsonConverter<T>.WriteAsPropertyName(Utf8JsonWriter, T, JsonSerializerOptions) e JsonConverter<T>.ReadAsPropertyName(Utf8JsonReader, Type, JsonSerializerOptions) consentono di aggiungere il supporto della chiave del dizionario per qualsiasi tipo di scelta.

Tipi non supportati

I tipi seguenti non sono supportati per la serializzazione:

Spazio dei nomi System.Data

Non sono disponibili convertitori predefiniti per DataSet, DataTablee i tipi correlati nello spazio dei nomi System.Data. La deserializzazione di questi tipi da un input non attendibile non è sicura, come illustrato in le linee guida per la sicurezza. Tuttavia, è possibile scrivere un convertitore personalizzato per supportare questi tipi. Per il codice del convertitore personalizzato di esempio che serializza e deserializza un DataTable, vedere RoundtripDataTable.cs.

Vedere anche