Idioma
Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Neste artigo, você aprenderá a serializar propriedades de classes derivadas com o System.Text.Json namespace.
Serializar propriedades de classes derivadas
A partir do .NET 7, System.Text.Json oferece suporte à serialização e desserialização de hierarquia de tipos polimórficos com anotações de atributo.
| Atributo | Descrição |
|---|---|
| JsonDerivedTypeAttribute | Quando colocado em uma declaração de tipo, indica que o subtipo especificado deve ser optado pela serialização polimórfica. Também expõe a capacidade de especificar um discriminador de tipo. |
| JsonPolymorphicAttribute | Quando colocado em uma declaração de tipo, indica que o tipo deve ser serializado polimorficamente. Ele também expõe várias opções para configurar a serialização polimórfica e a desserialização para esse tipo. |
Por exemplo, suponha que você tenha uma WeatherForecastBase classe e uma classe WeatherForecastWithCityderivada:
[JsonDerivedType(typeof(WeatherForecastWithCity))]
public class WeatherForecastBase
{
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public string? Summary { get; set; }
}
<JsonDerivedType(GetType(WeatherForecastWithCity))>
Public Class WeatherForecastBase
Public Property [Date] As DateTimeOffset
Public Property TemperatureCelsius As Integer
Public Property Summary As String
End Class
public class WeatherForecastWithCity : WeatherForecastBase
{
public string? City { get; set; }
}
Public Class WeatherForecastWithCity
Inherits WeatherForecastBase
Public Property City As String
End Class
E suponha que o argumento de tipo do método Serialize<TValue> em tempo de compilação seja WeatherForecastBase:
options = new JsonSerializerOptions
{
WriteIndented = true
};
jsonString = JsonSerializer.Serialize<WeatherForecastBase>(weatherForecastBase, options);
options = New JsonSerializerOptions With {
.WriteIndented = True
}
jsonString = JsonSerializer.Serialize(WeatherForecastBase, options)
Nesse cenário, a City propriedade é serializada porque o weatherForecastBase objeto é realmente um WeatherForecastWithCity objeto. Essa configuração permite a serialização polimórfica para WeatherForecastBase, especificamente quando o tipo de tempo de execução é WeatherForecastWithCity:
{
"City": "Milwaukee",
"Date": "2022-09-26T00:00:00-05:00",
"TemperatureCelsius": 15,
"Summary": "Cool"
}
Embora o retorno da carga útil como WeatherForecastBase seja suportado, ela não se concretizará como um tipo de execução em tempo de execução de WeatherForecastWithCity. Em vez disso, irá materializar-se como um tipo de tempo de execução de WeatherForecastBase:
WeatherForecastBase value = JsonSerializer.Deserialize<WeatherForecastBase>("""
{
"City": "Milwaukee",
"Date": "2022-09-26T00:00:00-05:00",
"TemperatureCelsius": 15,
"Summary": "Cool"
}
""");
Console.WriteLine(value is WeatherForecastWithCity); // False
Dim value As WeatherForecastBase = JsonSerializer.Deserialize(@"
{
"City": "Milwaukee",
"Date": "2022-09-26T00:00:00-05:00",
"TemperatureCelsius": 15,
"Summary": "Cool"
}")
Console.WriteLine(value is WeatherForecastWithCity) // False
A seção a seguir descreve como adicionar metadados para habilitar a ida e volta do tipo derivado.
Discriminadores de tipo polimórficos
Para habilitar a desserialização polimórfica, você deve especificar um discriminador de tipo para a classe derivada:
[JsonDerivedType(typeof(WeatherForecastBase), typeDiscriminator: "base")]
[JsonDerivedType(typeof(WeatherForecastWithCity), typeDiscriminator: "withCity")]
public class WeatherForecastBase
{
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public string? Summary { get; set; }
}
public class WeatherForecastWithCity : WeatherForecastBase
{
public string? City { get; set; }
}
<JsonDerivedType(GetType(WeatherForecastBase), "base")>
<JsonDerivedType(GetType(WeatherForecastWithCity), "withCity")>
Public Class WeatherForecastBase
Public Property [Date] As DateTimeOffset
Public Property TemperatureCelsius As Integer
Public Property Summary As String
End Class
Public Class WeatherForecastWithCity
Inherits WeatherForecastBase
Public Property City As String
End Class
Com os metadados adicionados, especificamente o discriminador de tipo, o serializador pode serializar e desserializar a carga como o tipo WeatherForecastWithCity a partir do seu tipo base WeatherForecastBase. A serialização emite JSON juntamente com os metadados do discriminador de tipo:
WeatherForecastBase weather = new WeatherForecastWithCity
{
City = "Milwaukee",
Date = new DateTimeOffset(2022, 9, 26, 0, 0, 0, TimeSpan.FromHours(-5)),
TemperatureCelsius = 15,
Summary = "Cool"
}
var json = JsonSerializer.Serialize<WeatherForecastBase>(weather, options);
Console.WriteLine(json);
// Sample output:
// {
// "$type" : "withCity",
// "City": "Milwaukee",
// "Date": "2022-09-26T00:00:00-05:00",
// "TemperatureCelsius": 15,
// "Summary": "Cool"
// }
Dim weather As WeatherForecastBase = New WeatherForecastWithCity With
{
.City = "Milwaukee",
.[Date] = New DateTimeOffset(2022, 9, 26, 0, 0, 0, TimeSpan.FromHours(-5)),
.TemperatureCelsius = 15,
.Summary = "Cool"
}
Dim json As String = JsonSerializer.Serialize(weather, options)
Console.WriteLine(json)
' Sample output:
' {
' "$type" : "withCity",
' "City": "Milwaukee",
' "Date": "2022-09-26T00:00:00-05:00",
' "TemperatureCelsius": 15,
' "Summary": "Cool"
' }
Com o discriminador de tipo, o serializador pode desserializar a carga polimorficamente como WeatherForecastWithCity:
WeatherForecastBase value = JsonSerializer.Deserialize<WeatherForecastBase>(json);
Console.WriteLine(value is WeatherForecastWithCity); // True
Dim value As WeatherForecastBase = JsonSerializer.Deserialize(json)
Console.WriteLine(value is WeatherForecastWithCity) // True
Nota
Por padrão, o $type discriminador deve ser colocado no início do objeto JSON, agrupado com outras propriedades de metadados como $id e $ref. Se você estiver lendo dados de uma API externa que coloca o $type discriminador no meio do objeto JSON, defina JsonSerializerOptions.AllowOutOfOrderMetadataProperties como true:
JsonSerializerOptions options = new() { AllowOutOfOrderMetadataProperties = true };
JsonSerializer.Deserialize<Base>("""{"Name":"Name","$type":"derived"}""", options);
Tenha cuidado ao ativar esta opção, pois pode resultar numa utilização excessiva do buffer (e em falhas por falta de memória) ao efetuar a desserialização em fluxo de objetos JSON muito grandes.
Misturar e combinar formatos discriminadores de tipo
Os identificadores discriminadores de tipo são válidos em qualquer uma das stringint formas, pelo que o seguinte é válido:
[JsonDerivedType(typeof(WeatherForecastWithCity), 0)]
[JsonDerivedType(typeof(WeatherForecastWithTimeSeries), 1)]
[JsonDerivedType(typeof(WeatherForecastWithLocalNews), 2)]
public class WeatherForecastBase { }
var json = JsonSerializer.Serialize<WeatherForecastBase>(new WeatherForecastWithTimeSeries());
Console.WriteLine(json);
// Sample output:
// {
// "$type" : 1,
// Omitted for brevity...
// }
<JsonDerivedType(GetType(WeatherForecastWithCity), 0)>
<JsonDerivedType(GetType(WeatherForecastWithTimeSeries), 1)>
<JsonDerivedType(GetType(WeatherForecastWithLocalNews), 2)>
Public Class WeatherForecastBase
End Class
Dim json As String = JsonSerializer.Serialize(Of WeatherForecastBase)(New WeatherForecastWithTimeSeries())
Console.WriteLine(json)
' Sample output:
' {
' "$type" : 1,
' Omitted for brevity...
' }
Embora a API permita combinar e alternar configurações de discriminador de tipo, isso não é recomendado. A recomendação geral é usar discriminadores todos do tipo string, discriminadores todos do tipo int ou não usar discriminadores. O exemplo seguinte mostra como combinar configurações do discriminador de tipo:
[JsonDerivedType(typeof(ThreeDimensionalPoint), typeDiscriminator: 3)]
[JsonDerivedType(typeof(FourDimensionalPoint), typeDiscriminator: "4d")]
public class BasePoint
{
public int X { get; set; }
public int Y { get; set; }
}
public class ThreeDimensionalPoint : BasePoint
{
public int Z { get; set; }
}
public sealed class FourDimensionalPoint : ThreeDimensionalPoint
{
public int W { get; set; }
}
<JsonDerivedType(GetType(ThreeDimensionalPoint), 3)>
<JsonDerivedType(GetType(FourDimensionalPoint), "4d")>
Public Class BasePoint
Public Property X As Integer
Public Property Y As Integer
End Class
Public Class ThreeDimensionalPoint
Inherits BasePoint
Public Property Z As Integer
End Class
Public NotInheritable Class FourDimensionalPoint
Inherits ThreeDimensionalPoint
Public Property W As Integer
End Class
No exemplo anterior, o tipo BasePoint não tem um discriminador de tipo, enquanto o tipo ThreeDimensionalPoint tem um discriminador de tipo int e o tipo FourDimensionalPoint tem um discriminador de tipo string.
Importante
Para que a serialização polimórfica funcione, o tipo do valor serializado deve ser o do tipo de base polimórfica. Isso inclui o uso do tipo base como o parâmetro de tipo genérico ao serializar valores de nível raiz, como o tipo declarado de propriedades serializadas ou como o elemento de coleção em coleções serializadas.
using System.Text.Json;
using System.Text.Json.Serialization;
PerformRoundTrip<BasePoint>();
PerformRoundTrip<ThreeDimensionalPoint>();
PerformRoundTrip<FourDimensionalPoint>();
static void PerformRoundTrip<T>() where T : BasePoint, new()
{
var json = JsonSerializer.Serialize<BasePoint>(new T());
Console.WriteLine(json);
BasePoint? result = JsonSerializer.Deserialize<BasePoint>(json);
Console.WriteLine($"result is {typeof(T)}; // {result is T}");
Console.WriteLine();
}
// Sample output:
// { "X": 541, "Y": 503 }
// result is BasePoint; // True
//
// { "$type": 3, "Z": 399, "X": 835, "Y": 78 }
// result is ThreeDimensionalPoint; // True
//
// { "$type": "4d", "W": 993, "Z": 427, "X": 508, "Y": 741 }
// result is FourDimensionalPoint; // True
Imports System.Text.Json
Imports System.Text.Json.Serialization
Module Program
Sub Main()
PerformRoundTrip(Of BasePoint)()
PerformRoundTrip(Of ThreeDimensionalPoint)()
PerformRoundTrip(Of FourDimensionalPoint)()
End Sub
Private Sub PerformRoundTrip(Of T As {BasePoint, New})()
Dim json = JsonSerializer.Serialize(Of BasePoint)(New T())
Console.WriteLine(json)
Dim result As BasePoint = JsonSerializer.Deserialize(Of BasePoint)(json)
Console.WriteLine($"result is {GetType(T)}; // {TypeOf result Is T}")
Console.WriteLine()
End Sub
End Module
' Sample output:
' { "X": 649, "Y": 754 }
' result is BasePoint; // True
'
' { "$type": 3, "Z": 247, "X": 814, "Y": 56 }
' result is ThreeDimensionalPoint; // True
'
' { "$type": "4d", "W": 427, "Z": 193, "X": 112, "Y": 935 }
' result is FourDimensionalPoint; // True
Personalizar o nome do discriminador de tipo
O nome da propriedade padrão para o discriminador de tipo é $type. Para personalizar o nome da propriedade, use o JsonPolymorphicAttribute como mostrado no exemplo a seguir:
[JsonPolymorphic(TypeDiscriminatorPropertyName = "$discriminator")]
[JsonDerivedType(typeof(ThreeDimensionalPoint), typeDiscriminator: "3d")]
public class BasePoint
{
public int X { get; set; }
public int Y { get; set; }
}
public sealed class ThreeDimensionalPoint : BasePoint
{
public int Z { get; set; }
}
<JsonPolymorphic(TypeDiscriminatorPropertyName:="$discriminator")>
<JsonDerivedType(GetType(ThreeDimensionalPoint), "3d")>
Public Class BasePoint
Public Property X As Integer
Public Property Y As Integer
End Class
Public Class ThreeDimensionalPoint
Inherits BasePoint
Public Property Z As Integer
End Class
No código anterior, o atributo JsonPolymorphic configura o TypeDiscriminatorPropertyName com o valor "$discriminator". Com o nome do discriminador de tipo configurado, o exemplo seguinte mostra o tipo ThreeDimensionalPoint serializado como JSON:
BasePoint point = new ThreeDimensionalPoint { X = 1, Y = 2, Z = 3 };
var json = JsonSerializer.Serialize<BasePoint>(point);
Console.WriteLine(json);
// Sample output:
// { "$discriminator": "3d", "X": 1, "Y": 2, "Z": 3 }
Dim point As BasePoint = New ThreeDimensionalPoint With { .X = 1, .Y = 2, .Z = 3 }
Dim json As String = JsonSerializer.Serialize(Of BasePoint)(point)
Console.WriteLine(json)
' Sample output:
' { "$discriminator": "3d", "X": 1, "Y": 2, "Z": 3 }
Sugestão
Evite usar uma propriedade JsonPolymorphicAttribute.TypeDiscriminatorPropertyName que entre em conflito com uma propriedade da sua hierarquia de tipos.
Processar tipos derivados desconhecidos
Para lidar com tipos derivados desconhecidos, você deve optar por esse suporte usando uma anotação no tipo base. Considere a seguinte hierarquia de tipo:
[JsonDerivedType(typeof(ThreeDimensionalPoint))]
public class BasePoint
{
public int X { get; set; }
public int Y { get; set; }
}
public class ThreeDimensionalPoint : BasePoint
{
public int Z { get; set; }
}
public class FourDimensionalPoint : ThreeDimensionalPoint
{
public int W { get; set; }
}
<JsonDerivedType(GetType(ThreeDimensionalPoint))>
Public Class BasePoint
Public Property X As Integer
Public Property Y As Integer
End Class
Public Class ThreeDimensionalPoint
Inherits BasePoint
Public Property Z As Integer
End Class
Public NotInheritable Class FourDimensionalPoint
Inherits ThreeDimensionalPoint
Public Property W As Integer
End Class
Como a configuração não opta explicitamente por suporte para FourDimensionalPoint, tentar serializar instâncias de FourDimensionalPoint como BasePoint resultará numa exceção em tempo de execução:
JsonSerializer.Serialize<BasePoint>(new FourDimensionalPoint()); // throws NotSupportedException
JsonSerializer.Serialize(Of BasePoint)(New FourDimensionalPoint()) ' throws NotSupportedException
Você pode alterar o comportamento padrão usando o JsonUnknownDerivedTypeHandling enum, que pode ser especificado da seguinte maneira:
[JsonPolymorphic(
UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)]
[JsonDerivedType(typeof(ThreeDimensionalPoint))]
public class BasePoint
{
public int X { get; set; }
public int Y { get; set; }
}
public class ThreeDimensionalPoint : BasePoint
{
public int Z { get; set; }
}
public class FourDimensionalPoint : ThreeDimensionalPoint
{
public int W { get; set; }
}
<JsonPolymorphic(
UnknownDerivedTypeHandling:=JsonUnknownDerivedTypeHandling.FallBackToBaseType)>
<JsonDerivedType(GetType(ThreeDimensionalPoint))>
Public Class BasePoint
Public Property X As Integer
Public Property Y As Integer
End Class
Public Class ThreeDimensionalPoint
Inherits BasePoint
Public Property Z As Integer
End Class
Public NotInheritable Class FourDimensionalPoint
Inherits ThreeDimensionalPoint
Public Property W As Integer
End Class
Em vez de voltar para o tipo base, você pode usar a FallBackToNearestAncestor configuração para retornar ao contrato do tipo derivado declarado mais próximo:
[JsonPolymorphic(
UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor)]
[JsonDerivedType(typeof(BasePoint))]
public interface IPoint { }
public class BasePoint : IPoint { }
public class ThreeDimensionalPoint : BasePoint { }
<JsonPolymorphic(
UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor)>
<JsonDerivedType(GetType(BasePoint)>
Public Interface IPoint
End Interface
Public Class BasePoint
Inherits IPoint
End Class
Public Class ThreeDimensionalPoint
Inherits BasePoint
End Class
Com uma configuração como a do exemplo anterior, o tipo ThreeDimensionalPoint será serializado como BasePoint:
// Serializes using the contract for BasePoint
JsonSerializer.Serialize<IPoint>(new ThreeDimensionalPoint());
' Serializes using the contract for BasePoint
JsonSerializer.Serialize(Of IPoint)(New ThreeDimensionalPoint())
No entanto, recorrer ao ancestral mais próximo introduz a possibilidade de ambiguidade em «diamante». Considere a seguinte hierarquia de tipo como exemplo:
[JsonPolymorphic(
UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor)]
[JsonDerivedType(typeof(BasePoint))]
[JsonDerivedType(typeof(IPointWithTimeSeries))]
public interface IPoint { }
public interface IPointWithTimeSeries : IPoint { }
public class BasePoint : IPoint { }
public class BasePointWithTimeSeries : BasePoint, IPointWithTimeSeries { }
<JsonPolymorphic(
UnknownDerivedTypeHandling:=JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor)>
<JsonDerivedType(GetType(BasePoint))>
<JsonDerivedType(GetType(IPointWithTimeSeries))>
Public Interface IPoint
End Interface
Public Interface IPointWithTimeSeries
Inherits IPoint
End Interface
Public Class BasePoint
Implements IPoint
End Class
Public Class BasePointWithTimeSeries
Inherits BasePoint
Implements IPointWithTimeSeries
End Class
Neste caso, o tipo BasePointWithTimeSeries pode ser serializado como BasePoint ou IPointWithTimeSeries, uma vez que ambos são ancestrais diretos. Essa ambiguidade fará com que o NotSupportedException seja lançado ao tentar serializar uma instância de BasePointWithTimeSeries como IPoint.
// throws NotSupportedException
JsonSerializer.Serialize<IPoint>(new BasePointWithTimeSeries());
' throws NotSupportedException
JsonSerializer.Serialize(Of IPoint)(New BasePointWithTimeSeries())
Inferir polimorfismo a partir de uma hierarquia fechada
A partir do .NET 11, System.Text.Json pode inferir tipos derivados de uma hierarquia fechada C# 15. Ativar a inferência numa hierarquia através de JsonPolymorphicAttribute.InferClosedTypePolymorphism:
[JsonPolymorphic(InferClosedTypePolymorphism = true)]
public closed class Shape { }
public sealed class Circle : Shape { }
public sealed class Square : Shape { }
O serializador regista cada tipo derivado e usa o seu nome simples como discriminador de cadeia. Por exemplo, uma Circle carga útil contém "$type":"Circle".
Para permitir inferência para cada hierarquia fechada que uma instância de opções trate, defina JsonSerializerOptions.InferClosedTypePolymorphism:
var options = new JsonSerializerOptions
{
InferClosedTypePolymorphism = true
};
Para geração de código-fonte, defina JsonSourceGenerationOptionsAttribute.InferClosedTypePolymorphism:
[JsonSourceGenerationOptions(InferClosedTypePolymorphism = true)]
[JsonSerializable(typeof(Shape))]
internal partial class AppJsonContext : JsonSerializerContext;
Define inferência no atributo de geração de origem quando usares um contexto gerado. Ativar apenas a propriedade de tempo de execução JsonSerializerOptions não permite adicionar metadados de tipos derivados que o gerador de origem não emitiu.
O atributo ao nível do tipo tem prioridade sobre o cenário global. Defina InferClosedTypePolymorphism = false em JsonPolymorphicAttribute para excluir uma hierarquia de uma definição global.
Os registos explícitos JsonDerivedTypeAttribute substituem a inferência nessa hierarquia. Eles não alargam a lista inferida. A aplicação de InferClosedTypePolymorphism = true a um tipo que não seja closed lança uma InvalidOperationException com serialização baseada em reflexão e produz um erro de geração de código-fonte. Tipos inferidos com nomes simples duplicados produzem colisões discriminadoras, e cada tipo inferido deve ser pelo menos tão acessível quanto a base fechada.
Configurar tipos derivados genéricos abertos
A partir do .NET 11, JsonDerivedTypeAttribute aceita um tipo generico aberto derivado quando o serializador pode resolver um tipo fechado único a partir do tipo base serializado:
[JsonDerivedType(typeof(Derived<>), "derived")]
public class Base<T>;
public class Derived<T> : Base<T>;
<JsonDerivedType(GetType(Derived(Of )), "derived")>
Public Class Base(Of T)
End Class
Public Class Derived(Of T)
Inherits Base(Of T)
End Class
Para Base<int>, o serializador regista Derived<int>. A mesma resolução suporta interfaces genéricas, parâmetros de tipo reordenados, argumentos genéricos aninhados, arrays e tipos derivados que fixam alguns argumentos de tipo base a tipos concretos.
Cada parâmetro de tipo derivado deve ser inferível a partir do tipo base fechado, a substituição deve ser inequívoca e o tipo resultante deve satisfazer as suas restrições genéricas. A serialização baseada em reflexão lança InvalidOperationException para uma especialização não suportada. A geração de código-fonte emite SYSLIB1229, e a hierarquia gerada continua a falhar quando o serializador a configura. Suprimir o aviso não torna o registo válido.
Configurar polimorfismo com o modelo de contrato
Para casos de uso em que as anotações de atributo são impraticáveis ou impossíveis (como modelos de domínio grande, hierarquias de montagem cruzada ou hierarquias em dependências de terceiros), para configurar o polimorfismo, use o modelo de contrato. O modelo de contrato é um conjunto de APIs que pode ser usado para configurar o polimorfismo em uma hierarquia de tipos, criando uma subclasse personalizada DefaultJsonTypeInfoResolver que fornece dinamicamente configuração polimórfica por tipo, conforme mostrado no exemplo a seguir:
public class PolymorphicTypeResolver : DefaultJsonTypeInfoResolver
{
public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)
{
JsonTypeInfo jsonTypeInfo = base.GetTypeInfo(type, options);
Type basePointType = typeof(BasePoint);
if (jsonTypeInfo.Type == basePointType)
{
jsonTypeInfo.PolymorphismOptions = new JsonPolymorphismOptions
{
TypeDiscriminatorPropertyName = "$point-type",
IgnoreUnrecognizedTypeDiscriminators = true,
UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FailSerialization,
DerivedTypes =
{
new JsonDerivedType(typeof(ThreeDimensionalPoint), "3d"),
new JsonDerivedType(typeof(FourDimensionalPoint), "4d")
}
};
}
return jsonTypeInfo;
}
}
Public Class PolymorphicTypeResolver
Inherits DefaultJsonTypeInfoResolver
Public Overrides Function GetTypeInfo(
ByVal type As Type,
ByVal options As JsonSerializerOptions) As JsonTypeInfo
Dim jsonTypeInfo As JsonTypeInfo = MyBase.GetTypeInfo(type, options)
Dim basePointType As Type = GetType(BasePoint)
If jsonTypeInfo.Type = basePointType Then
jsonTypeInfo.PolymorphismOptions = New JsonPolymorphismOptions With {
.TypeDiscriminatorPropertyName = "$point-type",
.IgnoreUnrecognizedTypeDiscriminators = True,
.UnknownDerivedTypeHandling =
JsonUnknownDerivedTypeHandling.FailSerialization
}
jsonTypeInfo.PolymorphismOptions.DerivedTypes.Add(
New JsonDerivedType(GetType(ThreeDimensionalPoint), "3d"))
jsonTypeInfo.PolymorphismOptions.DerivedTypes.Add(
New JsonDerivedType(GetType(FourDimensionalPoint), "4d"))
End If
Return jsonTypeInfo
End Function
End Class
Detalhes adicionais de serialização polimórfica
- A serialização polimórfica suporta tipos derivados que foram explicitamente incluídos através de JsonDerivedTypeAttribute. Tipos não declarados resultarão numa exceção em tempo de execução. O comportamento pode ser alterado configurando a JsonPolymorphicAttribute.UnknownDerivedTypeHandling propriedade.
- A configuração polimórfica especificada em tipos derivados não é herdada pela configuração polimórfica em tipos base. O tipo base deve ser configurado independentemente.
- As hierarquias polimórficas são suportadas para os tipos
interfaceeclass. - O polimorfismo usando discriminadores de tipo só é suportado para hierarquias de tipo que usam os conversores padrão para objetos, coleções e tipos de dicionário.
- O polimorfismo é suportado na geração de origem baseada em metadados, mas não na geração de origem de caminho rápido.