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:
- Deriva da IEnumerable o da IAsyncEnumerable<T>.
- Contiene elementi serializzabili.
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.
- dello spazio dei nomi System.Array
- spazio dei nomi System.Collections
- spazio dei nomi System.Collections.Generic
- spazio dei nomi System.Collections.Immutable
- dello spazio dei nomi System.Collections.Specialized
- spazio dei nomi System.Collections.Concurrent
- spazio dei nomi System.Collections.ObjectModel
- raccolte personalizzate
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
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 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 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:
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 di
, vedere round trip di supporto . † Vedere Tipi di chiave supportati.
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 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:
- System.Type e System.Reflection.MemberInfo
- ReadOnlySpan<T>, Span<T>e struct di riferimento in generale
- Tipi delegati
- IntPtr e UIntPtr
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.