Condividi tramite


Tipi di raccolta supportati in System.Text.Json

Questo articolo offre una panoramica delle raccolte supportate per la serializzazione e la deserializzazione. System.Text.Json.JsonSerializer supporta un tipo di raccolta per la serializzazione, se:

Il serializzatore chiama il GetEnumerator() metodo 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

Tipo Serializzazione Deserializzazione
Matrici unidimensionali ✔️ ✔️
Matrici multidimensionali
Matrici frastagliate ✔️ ✔️

Spazio dei nomi System.Collections

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

* Per i tipi, vedere La procedura Stack di andata e ritorno del supporto.

Spazio dei nomi System.Collections.Generic

Tipo 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 Il round trip del supporto per Stack i 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 IAsyncEnumerable<T> valori 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> I valori sono supportati solo dai metodi di serializzazione asincroni, ad esempio JsonSerializer.SerializeAsync.

Deserializzazione dei flussi

Il DeserializeAsyncEnumerable metodo 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 DeserializeAsyncEnumerable metodo supporta solo la lettura da matrici JSON a livello radice.

Il DeserializeAsync metodo 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> contenuti 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

Tipo 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, vedere La procedura Stack di andata e ritorno del supporto.

† Vedere Tipi di chiave supportati.

Spazio dei nomi System.Collections.Specialized

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

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

Spazio dei nomi System.Collections.Concurrent

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

* Per i tipi, vedere La procedura Stack di andata e ritorno del supporto.

† Vedere Tipi di chiave supportati.

Spazio dei nomi System.Collections.ObjectModel

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

* Lestring chiavi 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 (tutti gli elementi che derivano da IEnumerable) sono supportate per la serializzazione, purché siano supportati i relativi tipi di elemento.

Raccolte personalizzate con supporto per la deserializzazione

Una raccolta personalizzata è supportata per la deserializzazione, se:

Raccolte personalizzate con problemi noti

Esistono problemi noti con le raccolte personalizzate seguenti:

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

Tipi di chiave supportati

I tipi supportati per le chiavi di Dictionary e SortedList i tipi includono quanto segue:

  • 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
  • UInt16
  • UInt32
  • UInt64

Spazio dei nomi System.Data

Non sono disponibili convertitori predefiniti per DataSeti tipi , DataTablee correlati nello spazio dei System.Data nomi . La deserializzazione di questi tipi da un input non attendibile non è sicura, come illustrato nelle indicazioni sulla sicurezza. Tuttavia, è possibile scrivere un convertitore personalizzato per supportare questi tipi. Per il codice del convertitore personalizzato di esempio che serializza e deserializza un DataTableoggetto , vedere Round TripDataTable.cs.

Vedi anche