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:
- Deriva da IEnumerable o IAsyncEnumerable<T>
- Contiene elementi serializzabili.
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:
Non è un'interfaccia o un'astrazione.
Ha un costruttore senza parametri.
Contiene i tipi di elemento supportati da JsonSerializer.
Implementa o eredita una o più delle interfacce o classi seguenti:
- ConcurrentQueue<T>
- ConcurrentStack<T> *
- ICollection<T>
- IDictionary
- IDictionary<TKey,TValue> †
- IList
- IList<T>
- Queue
- Queue<T>
- Stack *
- Stack<T> *
* Per i tipi, vedere La procedura
Stack
di andata e ritorno del supporto.† Vedere Tipi di chiave supportati.
Raccolte personalizzate con problemi noti
Esistono problemi noti con le raccolte personalizzate seguenti:
- ExpandoObject: vedere dotnet/runtime#29690.
- DynamicObject: vedere dotnet/runtime#1808.
- DataTable: vedere dotnet/docs#21366.
- Microsoft.AspNetCore.Http.FormFile: vedere dotnet/runtime#1559.
- Microsoft.AspNetCore.Http.IFormCollection: vedere dotnet/runtime#1559.
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 DataTable
oggetto , vedere Round TripDataTable.cs.