Tipos de coleção suportados em System.Text.Json
Este artigo fornece uma visão geral de quais coleções são suportadas para serialização e desserialização. System.Text.Json.JsonSerializer Suporta um tipo de coleção para serialização se:
- Deriva de IEnumerable ou IAsyncEnumerable<T>
- Contém elementos que são serializáveis.
O serializador chama o GetEnumerator() método e grava os elementos.
A desserialização é mais complicada e não é suportada para alguns tipos de coleção.
As seções a seguir são organizadas por namespace e mostram quais tipos são suportados para serialização e desserialização.
Namespace System.Array
Tipo | Serialização | Desserialização |
---|---|---|
Matrizes unidimensionais | ✔️ | ✔️ |
Matrizes multidimensionais | ❌ | ❌ |
Matrizes irregulares | ✔️ | ✔️ |
Namespace System.Collections
Tipo | Serialização | Desserialização |
---|---|---|
ArrayList | ✔️ | ✔️ |
BitArray | ✔️ | ❌ |
DictionaryEntry | ✔️ | ✔️ |
Hashtable | ✔️ | ✔️ |
ICollection | ✔️ | ✔️ |
IDictionary | ✔️ | ✔️ |
IEnumerable | ✔️ | ✔️ |
IList | ✔️ | ✔️ |
Queue | ✔️ | ✔️ |
SortedList | ✔️ | ✔️ |
Stack * | ✔️ | ✔️ |
* Consulte Suporte ida e volta para Stack
tipos.
System.Collections.Generic namespace
Tipo | Serialização | Desserialização |
---|---|---|
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> ‡ | ✔️ | ✔️ |
* Consulte Tipos de chave suportados.
† Ver a secção seguinte em IAsyncEnumerable<T>
.
‡ Consulte Suporte ida e volta para Stack
tipos.
IAsyncEnumerable<T>
Os exemplos a seguir usam fluxos como uma representação de qualquer fonte assíncrona de dados. A origem pode ser arquivos em uma máquina local ou resultados de uma consulta de banco de dados ou chamada de API de serviço Web.
Serialização de fluxo
System.Text.Json
oferece suporte à serialização de IAsyncEnumerable<T> valores como matrizes JSON, conforme mostrado no exemplo a seguir:
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>
Os valores são suportados apenas pelos métodos de serialização assíncrona, como JsonSerializer.SerializeAsync.
Desserialização de fluxo
O DeserializeAsyncEnumerable
método oferece suporte à desserialização de streaming, conforme mostrado no exemplo a seguir:
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
O DeserializeAsyncEnumerable
método suporta apenas a leitura de matrizes JSON de nível raiz.
O DeserializeAsync método suporta IAsyncEnumerable<T>
, mas sua assinatura não permite streaming. Ele retorna o resultado final como um único valor, conforme mostrado no exemplo a seguir.
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
Neste exemplo, o desserializador armazena em buffer todo IAsyncEnumerable<T>
o conteúdo na memória antes de retornar o objeto desserializado. Esse comportamento é necessário porque o desserializador precisa ler toda a carga JSON antes de retornar um resultado.
System.Collections.Immutable namespace
Tipo | Serialização | Desserialização |
---|---|---|
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> * | ✔️ | ✔️ |
* Consulte Suporte ida e volta para Stack
tipos.
† Consulte Tipos de chave suportados.
System.Collections.Specialized namespace
Tipo | Serialização | Desserialização |
---|---|---|
BitVector32 | ✔️ | ❌* |
HybridDictionary | ✔️ | ✔️ |
IOrderedDictionary | ✔️ | ❌ |
ListDictionary | ✔️ | ✔️ |
NameValueCollection | ✔️ | ❌ |
StringCollection | ✔️ | ❌ |
StringDictionary | ✔️ | ❌ |
* Quando BitVector32 é desserializado, a propriedade é ignorada Data porque não tem um setter público. Não é gerada nenhuma exceção.
System.Collections.Concurrent namespace
Tipo | Serialização | Desserialização |
---|---|---|
BlockingCollection<T> | ✔️ | ❌ |
ConcurrentBag<T> | ✔️ | ❌ |
ConcurrentDictionary<TKey,TValue> † | ✔️ | ✔️ |
ConcurrentQueue<T> | ✔️ | ✔️ |
ConcurrentStack<T> * | ✔️ | ✔️ |
* Consulte Suporte ida e volta para Stack
tipos.
† Consulte Tipos de chave suportados.
System.Collections.ObjectModel namespace
Tipo | Serialização | Desserialização |
---|---|---|
Collection<T> | ✔️ | ✔️ |
String KeyedCollection<, TValue> * | ✔️ | ❌ |
ObservableCollection<T> | ✔️ | ✔️ |
ReadOnlyCollection<T> | ✔️ | ❌ |
ReadOnlyDictionary<TKey,TValue> | ✔️ | ❌ |
ReadOnlyObservableCollection<T> | ✔️ | ❌ |
* Não são suportadas chaves não.string
Coleções personalizadas
Qualquer tipo de coleção que não esteja em um dos namespaces anteriores é considerado uma coleção personalizada. Esses tipos incluem tipos definidos pelo usuário e tipos definidos pelo ASP.NET Core. Por exemplo, Microsoft.Extensions.Primitives está neste grupo.
Todas as coleções personalizadas (tudo o que deriva de ) são suportadas para serialização, desde que seus tipos de elemento sejam suportados IEnumerable
.
Coleções personalizadas com suporte a desserialização
Uma coleção personalizada é suportada para desserialização se:
Não é uma interface ou abstrato.
Tem um construtor sem parâmetros.
Contém tipos de elementos suportados pelo JsonSerializer.
Implementa ou herda uma ou mais das seguintes interfaces ou classes:
- ConcurrentQueue<T>
- ConcurrentStack<T> *
- ICollection<T>
- IDictionary
- IDictionary<TKey,TValue> †
- IList
- IList<T>
- Queue
- Queue<T>
- Stack *
- Stack<T> *
* Consulte Suporte ida e volta para
Stack
tipos.† Consulte Tipos de chave suportados.
Coleções personalizadas com problemas conhecidos
Há problemas conhecidos com as seguintes coleções personalizadas:
- ExpandoObject: Consulte dotnet/runtime#29690.
- DynamicObject: Consulte dotnet/runtime#1808.
- DataTable: Ver dotnet/docs#21366.
- Microsoft.AspNetCore.Http.FormFile: Consulte dotnet/runtime#1559.
- Microsoft.AspNetCore.Http.IFormCollection: Consulte dotnet/runtime#1559.
Para obter mais informações sobre problemas conhecidos, consulte os problemas abertos em System.Text.Json.
Tipos de chave suportados
Os tipos suportados para as chaves de Dictionary
e SortedList
tipos incluem o seguinte:
Boolean
Byte
DateTime
DateTimeOffset
Decimal
Double
Enum
Guid
Int16
Int32
Int64
Object
(Somente na serialização e se o tipo de tempo de execução for um dos tipos suportados nesta lista.)SByte
Single
String
UInt16
UInt32
UInt64
Namespace System.Data
Não há conversores internos para DataSet, DataTablee tipos relacionados no System.Data namespace. Desserializar esses tipos de entrada não confiável não é seguro, conforme explicado nas diretrizes de segurança. No entanto, você pode escrever um conversor personalizado para suportar esses tipos. Para obter um exemplo de código de conversor personalizado que serializa e desserializa um DataTable
, consulte RoundtripDataTable.cs.