Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Este artigo fornece uma visão geral de quais tipos são suportados para serialização e desserialização.
Tipos que serializam como objetos JSON
Os seguintes tipos serializam como objetos JSON:
- Aulas*
- Estruturas
- Interfaces
- Registos e registos struct
* Tipos não-dicionários que implementam IEnumerable<T> serializam como matrizes JSON. Os tipos de dicionário, que implementam IEnumerable<T>, serializam como objetos JSON.
O trecho de código a seguir mostra a serialização de uma estrutura simples.
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; }
}
Tipos que serializam como matrizes JSON
Os tipos de coleção .NET serializam como matrizes JSON. System.Text.Json.JsonSerializer oferece suporte a 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 método GetEnumerator() 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.
- de namespace System.Array
- de namespace System.Collections
- de namespace System.Collections.Generic
- de namespace System.Collections.Immutable
- de namespace System.Collections.Specialized
- de namespace System.Collections.Concurrent
- de namespace System.Collections.ObjectModel
- Coleções personalizadas
Namespace System.Array
| Tipo | Serialização | Desserialização |
|---|---|---|
| Matrizes unidimensionais* | ✔️ | ✔️ |
| Matrizes multidimensionais | ❌ | ❌ |
| Matrizes irregulares | ✔️ | ✔️ |
*
byte[] é manipulado especialmente e serializa como uma cadeia de caracteres base64, não como uma matriz JSON.
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 sobre 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 valores IAsyncEnumerable<T> 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> valores são suportados apenas pelos métodos de serialização assíncrona, como JsonSerializer.SerializeAsync.
Desserialização de fluxo
O método DeserializeAsyncEnumerable 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 método DeserializeAsyncEnumerable suporta apenas a leitura de matrizes JSON de nível raiz.
O método DeserializeAsync 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> 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 Data é ignorada porque não tem um setter público. Nenhuma exceção é lançada.
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> | ✔️ | ✔️ |
| KeyedCollection<string, TValue> * | ✔️ | ❌ |
| ObservableCollection<T> | ✔️ | ✔️ |
| ReadOnlyCollection<T> | ✔️ | ❌ |
| ReadOnlyDictionary<TKey,TValue> | ✔️ | ❌ |
| ReadOnlyObservableCollection<T> | ✔️ | ❌ |
* As chaves nãostring não são suportadas.
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 IEnumerable) são suportadas para serialização, desde que seus tipos de elementos sejam suportados.
Suporte à 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
Stacktipos.† Consulte Tipos de chave suportados.
Problemas conhecidos
Há problemas conhecidos com as seguintes coleções personalizadas:
- ExpandoObject: Consulte dotnet/runtime#29690.
- DynamicObject: Consulte dotnet/runtime#1808.
- DataTable: Veja 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 em aberto no System.Text.Json.
Tipos de chave suportados
Quando usados como as chaves dos tipos Dictionary e SortedList, os seguintes tipos têm suporte interno:
BooleanByteDateTimeDateTimeOffsetDecimalDoubleEnumGuidInt16Int32Int64-
Object(Somente na serialização e se o tipo de tempo de execução for um dos tipos suportados nesta lista.) SByteSingleString- TimeSpan
UInt16UInt32UInt64- Uri
- Version
Além disso, os métodos JsonConverter<T>.WriteAsPropertyName(Utf8JsonWriter, T, JsonSerializerOptions) e JsonConverter<T>.ReadAsPropertyName(Utf8JsonReader, Type, JsonSerializerOptions) permitem adicionar suporte a chaves de dicionário para qualquer tipo de sua escolha.
Tipos não suportados
Os seguintes tipos não são suportados para serialização:
- System.Type e System.Reflection.MemberInfo
- ReadOnlySpan<T>, Span<T>e ref structs em geral
- Tipos de delegados
- IntPtr e UIntPtr
Namespace System.Data
Não há conversores internos para DataSet, DataTablee tipos relacionados no namespace System.Data. Desserializar esses tipos de entrada não confiável não é seguro, conforme explicado em as 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.