Nota
L'accés a aquesta pàgina requereix autorització. Podeu provar d'iniciar la sessió o de canviar els directoris.
L'accés a aquesta pàgina requereix autorització. Podeu provar de canviar els directoris.
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 | ✔️ | ✔️ |
*
byte[] se controla especialmente y serializa como una cadena base64, no como una matriz JSON.
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> | ✔️ | ✔️ |
| IReadOnlySet<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.
§ System.Text.Json admite IReadOnlySet<T> en .NET 11 y versiones posteriores. Al deserializar la interfaz, el serializador crea una HashSet<T> instancia. Para los metadatos generados, JsonMetadataServices.CreateIReadOnlySetInfo crea el contrato de recopilación.
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.
En .NET 11 y versiones posteriores, JsonSerializer.SerializeAsyncEnumerable escribe una IAsyncEnumerable<T> secuencia en o Stream en .PipeWriter Con el valor predeterminado topLevelValues: false, el método escribe una única matriz JSON de nivel raíz. Establezca topLevelValues: true para escribir líneas JSON en su lugar, donde cada elemento es un valor de nivel superior independiente:
{"id":1,"name":"apple"}
{"id":2,"name":"banana"}
El método escribe una sola fuente de líneas (LF), \n, después de cada valor, incluido el último. Siempre usa LF, independientemente de JsonSerializerOptions.NewLine. El método omite JsonSerializerOptions.WriteIndented, por lo que cada valor permanece en una línea.
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
De forma predeterminada, JsonSerializer.DeserializeAsyncEnumerable lee elementos de una sola matriz JSON de nivel raíz. Establézcalo topLevelValues: true para leer una secuencia de valores de nivel superior separados por espacios en blanco en su lugar. Este formato de entrada es un superconjunto de líneas JSON. Las sobrecargas aceptan o Stream .PipeReader
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
Stacktipos.† 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:
- BFloat16(.NET 11 y versiones posteriores)
BooleanByteDateTimeDateTimeOffsetDecimal- Decimal32(.NET 11 y versiones posteriores)
- Decimal64(.NET 11 y versiones posteriores)
- Decimal128(.NET 11 y versiones posteriores)
DoubleEnumGuidInt16Int32Int64-
Object(solo en la serialización y si el tipo en tiempo de ejecución es uno de los tipos admitidos en esta lista). SByteSingleString- TimeSpan
UInt16UInt32UInt64- 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 de punto flotante BFloat16 y decimales
A partir de .NET 11, System.Text.Json incluye convertidores integrados para los BFloat16tipos , Decimal32, Decimal64y Decimal128 . Los valores finitos se serializan como números JSON.
Estos tipos se comportan como los otros tipos numéricos integrados:
- La conversión de clave de diccionario admite los cuatro tipos.
- Respetan JsonNumberHandling, incluidos los
"NaN"literales ,"Infinity"y"-Infinity"a través AllowNamedFloatingPointLiteralsde .
JsonMetadataServices expone las propiedades del convertidor para los metadatos generados por el origen. Las propiedades son JsonMetadataServices.BFloat16Converter, JsonMetadataServices.Decimal32Converter, JsonMetadataServices.Decimal64Converter y JsonMetadataServices.Decimal128Converter.
Uniones discriminadas de F#
A partir de .NET 11, System.Text.Json serializa y deserializa uniones discriminadas de F#, incluidas las uniones de clase, estructura y recursivas:
type Shape =
| Point
| Circle of radius: float
- Un caso sin campos serializa como una cadena JSON que contiene el nombre de caso, como
"Point". - Un caso que tiene campos serializa como un objeto JSON. El objeto contiene un
$typediscriminador seguido de los campos con nombre del caso, como{"$type":"Circle","radius":3.14}.
JsonSerializerOptions.PropertyNamingPolicy se aplica a los nombres de mayúsculas y minúsculas y a los nombres de campo. Un nivel JsonPropertyNameAttribute de caso tiene prioridad. Para usar un nombre de propiedad discriminador distinto de $type, establezca JsonPolymorphicAttribute.TypeDiscriminatorPropertyName.
Importante
El soporte de unión discriminado de F# es de solo reflexión. Requiere código dinámico y metadatos de reflexión no filtrados. No se puede usar con la generación de origen ni con System.Text.Json AOT nativo.
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