Serialización polimórfica de tipos de objeto
Con la configuración predeterminada, System.Text.Json serializa los valores de tipo object
mediante polimorfismo. Este comportamiento es menos coherente si se registra un convertidor personalizado para object
. Históricamente, System.Text.Json
ha codificado de forma rígida el polimorfismo de los valores de objeto de nivel raíz, pero no de los valores de objeto anidados. A partir de .NET 7, este comportamiento ha cambiado para que los convertidores personalizados no usen nunca polimorfismo.
Comportamiento anterior
Veamos el siguiente convertidor de objetos personalizado:
public class CustomObjectConverter : JsonConverter<object>
{
public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options)
=> writer.WriteNumberValue(42);
public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> throw new NotImplementedException();
}
En versiones anteriores, el código siguiente se serializaba como 0. Esto se debe a que el serializador usaba polimorfismo y omitía el convertidor personalizado.
var options = new JsonSerializerOptions { Converters = { new CustomObjectConverter() } };
JsonSerializer.Serialize<object>(0, options);
Sin embargo, el siguiente código se serializaba como 42 porque el serializador respetaba el convertidor personalizado.
var options = new JsonSerializerOptions { Converters = { new CustomObjectConverter() } };
JsonSerializer.Serialize<object[]>(new object[] { 0 }, options);
Comportamiento nuevo
A partir de .NET 7, al usar el convertidor de objetos personalizado definido en la sección Comportamiento anterior, el código siguiente se serializa como 42. Esto se debe a que el serializador siempre consultará al convertidor personalizado, y no usará polimorfismo.
var options = new JsonSerializerOptions { Converters = { new CustomObjectConverter() } };
JsonSerializer.Serialize<object>(0, options);
Versión introducida
.NET 7
Tipo de cambio importante
Este cambio puede afectar a la compatibilidad binaria.
Motivo del cambio
Este cambio se ha realizado debido a que los contratos de serialización de un tipo eran incoherentes, según si este se serializaba como un valor de nivel raíz o como un valor anidado.
Acción recomendada
Si lo desea, puede recuperar el uso del polimorfismo con los valores de nivel raíz, invocando para ello uno de los métodos de serialización sin tipo:
var options = new JsonSerializerOptions { Converters = { new CustomObjectConverter() } };
JsonSerializer.Serialize(0, inputType: typeof(int), options); // Serializes as 0.
API afectadas
- System.Text.Json.JsonSerializer.Serialize<TValue>(TValue, JsonSerializerOptions)
- System.Text.Json.JsonSerializer.Serialize<TValue>(Stream, TValue, JsonSerializerOptions)
- System.Text.Json.JsonSerializer.Serialize<TValue>(Utf8JsonWriter, TValue, JsonSerializerOptions)
- System.Text.Json.JsonSerializer.SerializeAsync<TValue>(Stream, TValue, JsonSerializerOptions, CancellationToken)
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente GitHub Issues como mecanismo de comentarios sobre el contenido y lo sustituiremos por un nuevo sistema de comentarios. Para más información, vea:Enviar y ver comentarios de