Tipos admitidos en System.Text.Json
En este artículo se proporciona información general sobre qué tipos se admiten para la serialización y deserialización.
Tipos que serializan como objetos JSON
Los siguientes tipos se serializan como objetos JSON:
- Clases*
- Estructuras
- Interfaces
- Registros y registros de estructura
* Tipos que no son diccionarios que implementan IEnumerable<T> serializar como matrices JSON. Los tipos de diccionario, que implementan IEnumerable<T>, serializan como objetos JSON.
El siguiente fragmento de código muestra la serialización de una estructura simple.
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 serializan como matrices JSON
Los tipos de colección de .NET serializan como matrices JSON. System.Text.Json.JsonSerializer admite un tipo de colección para la serialización si:
- Deriva de IEnumerable o IAsyncEnumerable<T>.
- Contiene elementos serializables.
El serializador llama al método GetEnumerator() y escribe los elementos.
La deserialización es más complicada y no se admite para algunos tipos de colección.
Las secciones siguientes se organizan por espacio de nombres y muestran qué tipos se admiten para la serialización y deserialización.
- espacio de nombres System.Array
- espacio de nombres System.Collections
- espacio de nombres System.Collections.Generic
- espacio de nombres System.Collections.Immutable
- espacio de nombres System.Collections.Specialized
- espacio de nombres System.Collections.Concurrent
- espacio de nombres System.Collections.ObjectModel
- colecciones personalizadas
Espacio de nombres System.Array
Tipo | Serialización | Deserialización |
---|---|---|
matrices unidimensionales | ✔️ | ✔️ |
matrices multidimensionales | ❌ | ❌ |
matrices jagged | ✔️ | ✔️ |
Espacio de nombres System.Collections
Tipo | Serialización | Deserialización |
---|---|---|
ArrayList | ✔️ | ✔️ |
BitArray | ✔️ | ❌ |
DictionaryEntry | ✔️ | ✔️ |
Hashtable | ✔️ | ✔️ |
ICollection | ✔️ | ✔️ |
IDictionary | ✔️ | ✔️ |
IEnumerable | ✔️ | ✔️ |
IList | ✔️ | ✔️ |
Queue | ✔️ | ✔️ |
SortedList | ✔️ | ✔️ |
Stack * | ✔️ | ✔️ |
* Consulte recorrido de ida y vuelta de soporte técnico para Stack
tipos.
Espacio de nombres System.Collections.Generic
Tipo | Serialización | Deserialización |
---|---|---|
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> † | ✔️ | ✔️ |
* Vea tipos de clave admitidos.
† Consulte la sección siguiente sobre IAsyncEnumerable<T>
.
† Consulte recorrido de ida y vuelta de soporte técnico para Stack
tipos.
IAsyncEnumerable<T>
En los ejemplos siguientes se usan secuencias como representación de cualquier origen asincrónico de datos. El origen podría ser archivos en un equipo local o resultados de una consulta de base de datos o una llamada API de servicio web.
Serialización de secuencias
System.Text.Json
admite la serialización de valores IAsyncEnumerable<T> como matrices JSON, como se muestra en el ejemplo siguiente:
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]}
los métodos de serialización asincrónica solo admiten IAsyncEnumerable<T>
valores, como JsonSerializer.SerializeAsync.
Deserialización de flujos
El método DeserializeAsyncEnumerable
admite la deserialización de streaming, como se muestra en el ejemplo siguiente:
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
El método DeserializeAsyncEnumerable
solo admite la lectura de matrices JSON de nivel raíz.
El método DeserializeAsync admite IAsyncEnumerable<T>
, pero su firma no permite el streaming. Devuelve el resultado final como un valor único, como se muestra en el ejemplo siguiente.
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
En este ejemplo, el deserializador almacena en búfer todo el contenido de IAsyncEnumerable<T>
en memoria antes de devolver el objeto deserializado. Este comportamiento es necesario porque el deserializador debe leer toda la carga JSON antes de devolver un resultado.
Espacio de nombres System.Collections.Immutable
Tipo | Serialización | Deserialización |
---|---|---|
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 recorrido de ida y vuelta de soporte técnico para Stack
tipos.
† Vea tipos de clave admitidos.
Espacio de nombres System.Collections.Specialized
Tipo | Serialización | Deserialización |
---|---|---|
BitVector32 | ✔️ | ❌* |
HybridDictionary | ✔️ | ✔️ |
IOrderedDictionary | ✔️ | ❌ |
ListDictionary | ✔️ | ✔️ |
NameValueCollection | ✔️ | ❌ |
StringCollection | ✔️ | ❌ |
StringDictionary | ✔️ | ❌ |
* Cuando se deserializa BitVector32, se omite la propiedad Data porque no tiene un establecedor público. No se produce ninguna excepción.
Espacio de nombres System.Collections.Concurrent
Tipo | Serialización | Deserialización |
---|---|---|
BlockingCollection<T> | ✔️ | ❌ |
ConcurrentBag<T> | ✔️ | ❌ |
ConcurrentDictionary<TKey,TValue> † | ✔️ | ✔️ |
ConcurrentQueue<T> | ✔️ | ✔️ |
ConcurrentStack<T> * | ✔️ | ✔️ |
* Consulte recorrido de ida y vuelta de soporte técnico para Stack
tipos.
† Vea tipos de clave admitidos.
Espacio de nombres System.Collections.ObjectModel
Tipo | Serialización | Deserialización |
---|---|---|
Collection<T> | ✔️ | ✔️ |
cadena de<KeyedCollection,> * TValue | ✔️ | ❌ |
ObservableCollection<T> | ✔️ | ✔️ |
ReadOnlyCollection<T> | ✔️ | ❌ |
ReadOnlyDictionary<TKey,TValue> | ✔️ | ❌ |
ReadOnlyObservableCollection<T> | ✔️ | ❌ |
* No se admiten claves nostring
.
Colecciones personalizadas
Cualquier tipo de colección que no se encuentra en uno de los espacios de nombres anteriores se considera una colección personalizada. Estos tipos incluyen tipos definidos por el usuario y tipos definidos por ASP.NET Core. Por ejemplo, Microsoft.Extensions.Primitives está en este grupo.
Todas las colecciones personalizadas (todo lo que deriva de IEnumerable
) se admiten para la serialización, siempre y cuando se admitan sus tipos de elementos.
Compatibilidad con la deserialización
Se admite una colección personalizada para la deserialización si:
No es una interfaz ni abstracta.
Tiene un constructor sin parámetros.
Contiene tipos de elementos admitidos por JsonSerializer.
Implementa o hereda una o varias de las siguientes interfaces o clases:
- ConcurrentQueue<T>
- ConcurrentStack<T> *
- ICollection<T>
- IDictionary
- IDictionary<TKey,TValue> †
- IList
- IList<T>
- Queue
- Queue<T>
- Stack *
- Stack<T> *
* Consulte recorrido de ida y vuelta de soporte técnico para
Stack
tipos.† Vea tipos de clave admitidos.
Problemas conocidos
Hay problemas conocidos con las siguientes colecciones personalizadas:
- ExpandoObject: vea dotnet/runtime#29690.
- DynamicObject: vea dotnet/runtime#1808.
- DataTable: vea dotnet/docs#21366.
- Microsoft.AspNetCore.Http.FormFile: vea dotnet/runtime#1559.
- Microsoft.AspNetCore.Http.IFormCollection: vea dotnet/runtime#1559.
Para obtener más información sobre los problemas conocidos, consulte la problemas abiertos en System.Text.Json.
Tipos de clave admitidos
Cuando se usa como claves de tipos de Dictionary
y SortedList
, los siguientes tipos tienen compatibilidad integrada:
Boolean
Byte
DateTime
DateTimeOffset
Decimal
Double
Enum
Guid
Int16
Int32
Int64
-
Object
(solo en la serialización y si el tipo en tiempo de ejecución es uno de los tipos admitidos en esta lista). SByte
Single
String
- TimeSpan
UInt16
UInt32
UInt64
- Uri
- Version
Además, los métodos JsonConverter<T>.WriteAsPropertyName(Utf8JsonWriter, T, JsonSerializerOptions) y JsonConverter<T>.ReadAsPropertyName(Utf8JsonReader, Type, JsonSerializerOptions) permiten agregar compatibilidad con claves de diccionario para cualquier tipo de su elección.
Tipos no admitidos
No se admiten los siguientes tipos para la serialización:
- System.Type y System.Reflection.MemberInfo
- ReadOnlySpan<T>, Span<T>y estructuras ref en general
- Tipos delegados
- IntPtr y UIntPtr
Espacio de nombres System.Data
No hay convertidores integrados para DataSet, DataTabley tipos relacionados en el espacio de nombres System.Data. La deserialización de estos tipos de entradas que no son de confianza no es segura, como se explica en la guía de seguridad. Sin embargo, puede escribir un convertidor personalizado para admitir estos tipos. Para obtener código de convertidor personalizado de ejemplo que serializa y deserializa un DataTable
, vea RoundtripDataTable.cs.
Consulte también
- Rellenar las propiedades inicializadas
- información general de System.Text.Json
- System.Text.Json de referencia de API
- System.Text.Json. Referencia de api de serialización