Compartilhar via


Serialização Stand-alone JSON usando DataContractJsonSerializer

Observação

Este artigo é sobre DataContractJsonSerializer. Para a maioria dos cenários que envolvem serialização e desserialização do JSON, recomendamos as APIs no namespace System.Text.Json.

JSON (JavaScript Object Notation) é um formato de dados projetado especificamente para ser usado pelo código JavaScript em execução em páginas da Web dentro do navegador. É o formato de dados padrão usado pelos serviços ASP.NET AJAX criados no Windows Communication Foundation (WCF).

Esse formato também pode ser usado ao criar serviços AJAX sem integração com ASP.NET – nesse caso, XML é o padrão, mas JSON pode ser escolhido.

Por fim, se você precisar de suporte de JSON, mas não estiver criando um serviço AJAX, o DataContractJsonSerializer possibilita serializar diretamente objetos .NET em dados JSON e desserializar esses dados de volta em instâncias de tipos .NET. Para obter uma descrição de como fazer isso, consulte Como serializar e desserializar dados JSON.

Ao trabalhar com JSON, há suporte para os mesmos tipos de .NET, com algumas exceções, conforme são compatíveis com o DataContractSerializer. Para obter uma lista completa de tipos compatíveis, confira Tipos compatíveis com o Serializador de Contrato de Dados. Isso inclui a maioria dos tipos primitivos, a maioria dos tipos de matriz e coleção, bem como tipos complexos que usam o DataContractAttribute e DataMemberAttribute.

Mapear tipos de .NET para tipos de JSON

A tabela a seguir mostra a correspondência entre tipos de .NET e tipos de JSON/JavaScript quando mapeada por procedimentos de serialização e desserialização.

Tipos de .NET JSON/JavaScript Observações
Todos os tipos numéricos, por exemplo Int32, Decimal ou Double Número Valores especiais, como Double.NaN, Double.PositiveInfinity e Double.NegativeInfinity não são compatíveis e resultam em JSON inválido.
Enum Número Confira "Enumerações e JSON" mais adiante neste artigo.
Boolean Boolean
String, Char String
TimeSpan, Guid, Uri String O formato desses tipos em JSON é o mesmo que em XML (essencialmente, intervalo de tempo no formato de Duração ISO 8601, GUID no formato "12345678-ABCD-ABCD-ABCD-1234567890AB" e URI em sua forma de cadeia de caracteres natural, como ""http://www.example.com";). Para saber mais, confira Referência de esquema de contrato de dados.
XmlQualifiedName String O formato é "name:namespace" (qualquer coisa antes dos primeiros dois-pontos é o nome). O nome ou o namespace podem estar ausentes. Se não houver namespace, os dois-pontos também poderão ser omitidos.
Array do tipo Byte Matriz de números Cada número representa o valor de um byte.
DateTime DateTime ou Cadeia de Caracteres Consulte Datas/Horas e JSON mais adiante neste artigo.
DateTimeOffset Tipo complexo Consulte Datas/Horas e JSON mais adiante neste artigo.
Tipos de XML e ADO.NET (XmlElement,

XElement. Matrizes de XmlNode,

ISerializable,

DataSet).
String Consulte a seção Tipos de XML e JSON deste artigo.
DBNull Tipo complexo vazio --
Coleções, dicionários e matrizes Array Consulte a seção Coleções, Dicionários e Matrizes deste tópico.
Tipos complexos (com o DataContractAttribute ou SerializableAttribute aplicado) Tipo complexo Os membros de dados tornam-se membros do tipo complexo JavaScript.
Tipos complexos que implementam a interface ISerializable) Tipo complexo O mesmo que outros tipos complexos, mas alguns ISerializable tipos não são compatíveis – consulte Suporte ISerializable.
valor Null para qualquer tipo Null Os tipos de valor anuláveis também são compatíveis e são mapeados para JSON da mesma forma que tipos de valor não anuláveis.

Enumerações e JSON

Os valores de membro de enumeração são tratados como números em JSON, que é diferente de como eles são tratados em contratos de dados, em que são incluídos como nomes de membro. Para obter mais informações sobre o tratamento do contrato de dados, consulte Tipos de enumeração em contratos de dados.

  • Por exemplo, se você tiver public enum Color {red, green, blue, yellow, pink}, a serialização yellow produzirá o número 3 e não a cadeia de caracteres "yellow".

  • Todos os enum membros são serializáveis. Os atributos EnumMemberAttribute e NonSerializedAttribute são ignorados se usados.

  • É possível desserializar um valor inexistente enum – por exemplo, o valor 87 pode ser desserializado na enumeração Color anterior, embora não haja nenhum nome de cor correspondente definido.

  • Um sinalizador enum não é especial e é tratado da mesma forma que qualquer outro enum.

Datas/horas e JSON

O formato JSON não dá suporte diretamente a datas e horas. No entanto, eles são muito comumente usados e ASP.NET AJAX fornece suporte especial para esses tipos. Ao usar proxies ASP.NET AJAX, o tipo DateTime no .NET corresponde totalmente ao tipo DateTime em JavaScript.

  • Ao não usar ASP.NET, um tipo DateTime é representado em JSON como uma cadeia de caracteres com um formato especial descrito na seção Informações Avançadas deste tópico.

  • DateTimeOffset é representado em JSON como um tipo complexo: {"DateTime":dateTime,"OffsetMinutes":offsetMinutes}. O membro offsetMinutes é o deslocamento de hora local do Tempo Médio de Greenwich (GMT), também conhecido como Tempo Universal Coordenado (UTC), associado ao local do evento de interesse. O membro dateTime representa a instância no tempo em que o evento de interesse ocorreu (novamente, ele se torna um DateTime em JavaScript quando ASP.NET AJAX está em uso, e uma cadeia de caracteres quando não está). Na serialização, o membro dateTime é sempre serializado em GMT. Portanto, se estiver descrevendo 3h de Nova York, dateTime terá um componente de tempo de 8h e offsetMinutes será 300 (menos 300 minutos ou 5 horas de GMT).

    Observação

    Os objetos DateTime e DateTimeOffset, quando serializados para JSON, preservam apenas as informações para precisão de milissegundos. Valores abaixo de milissegundos (micro/nanossegundos) são perdidos durante a serialização.

Tipos de XML e JSON

Os tipos de XML tornam-se cadeias de caracteres JSON.

  • Por exemplo, se um membro de dados "q" do tipo XElement contiver <abc/>, o JSON será {"q":"<abc/>"}.

  • Há algumas regras especiais que especificam como o XML é encapsulado. Para obter mais informações, consulte a seção Informações Avançadas mais adiante neste artigo.

  • Se você estiver usando ASP.NET AJAX e não quiser usar cadeias de caracteres no JavaScript, mas quiser o XML DOM, defina a propriedade ResponseFormat como XML em WebGetAttribute ou a propriedade ResponseFormat como XML em WebInvokeAttribute.

Coleções, dicionários e matrizes

Todas as coleções, dicionários e matrizes são representados em JSON como matrizes.

  • Qualquer personalização que usa o CollectionDataContractAttribute é ignorada na representação JSON.

  • Dicionários não são uma maneira de trabalhar diretamente com JSON. O dicionário <string.object> pode não ser compatível da mesma forma que o WCF, conforme o esperado, de trabalhar com outras tecnologias JSON. Por exemplo, se "abc" for mapeado para "xyz" e "def" for mapeado para 42 em um dicionário, a representação JSON não será {"abc":"xyz","def":42} mas será [{"Key":"abc","Value":"xyz"},{"Key":"def","Value":42}] em vez disso.

  • Se você quiser trabalhar diretamente com JSON (acessando chaves e valores dinamicamente, sem pré-definir um contrato rígido), terá várias opções:

    • Considere usar o exemplo Serialização JSON de tipo fraco (AJAX).

    • Considere usar os ISerializable construtores de interface e desserialização – esses dois mecanismos permitem que você acesse pares chave/valor JSON na serialização e desserialização, respectivamente, mas não funcionam em cenários de confiança parcial.

    • Considere trabalhar com o mapeamento entre JSON e XML em vez de usar um serializador.

    • O polimorfismo no contexto da serialização refere-se à capacidade de serializar um tipo derivado em que seu tipo base é esperado. Há regras especiais específicas de JSON ao usar coleções polimorficamente, quando, por exemplo, atribuir uma coleção a um Object. Esse problema é mais discutido na seção Informações Avançadas mais adiante neste artigo.

Additional Details

Ordem dos membros de dados

A ordem dos membros de dados não é importante ao usar JSON. Especificamente, mesmo que Order esteja definido, os dados JSON ainda poderão ser desserializados em qualquer ordem.

Tipos de JSON

O tipo de JSON não precisa corresponder à tabela anterior na desserialização. Por exemplo, um Int normalmente é mapeado para um número JSON, mas também pode ser desserializado com êxito de uma cadeia de caracteres JSON, desde que essa cadeia de caracteres contenha um número válido. Ou seja, {"q":42} e {"q":"42"} são válidos se houver um membro de dados Int chamado "q".

Polimorfismo

A serialização polimórfica consiste na capacidade de serializar um tipo derivado em que seu tipo base é esperado. Este é compatível com a serialização JSON pelo WCF comparável à maneira como a serialização XML é compatível. Por exemplo, você pode serializar MyDerivedType onde MyBaseType é esperado ou serializar Int onde Object é esperado.

As informações de tipo podem ser perdidas ao desserializar um tipo derivado se o tipo base for esperado, a menos que você esteja desserializando um tipo complexo. Por exemplo, se Uri for serializado onde Object é esperado, isso resultará em uma cadeia de caracteres JSON. Se essa cadeia de caracteres for desserializada novamente em Object, um .NET String será retornado. O desserializador não sabe que a cadeia de caracteres era inicialmente do tipo Uri. Geralmente, ao esperar Object, todas as cadeias de caracteres JSON são desserializadas como cadeias de caracteres .NET e todas as matrizes JSON usadas para serializar coleções, dicionários e matrizes do .NET são desserializadas como .NET Array do tipo Object, independentemente do tipo original real. Um JSON booliano é mapeado para um .NET Boolean. No entanto, ao esperar um Object, os números JSON são desserializados como .NET Int32, Decimal ou Double, em que o tipo mais apropriado é escolhido automaticamente.

Ao desserializar em um tipo de interface, o DataContractJsonSerializer desserializa como se o tipo declarado fosse objeto.

Ao trabalhar com sua própria base e tipos derivados, usar o KnownTypeAttribute, ServiceKnownTypeAttribute ou um mecanismo equivalente normalmente é necessário. Por exemplo, se você tiver uma operação que tenha um valor retornado Animal e ela realmente retornar uma instância de Cat (derivada de Animal), você deverá aplicar o KnownTypeAttribute, ao tipo Animal ou o ServiceKnownTypeAttribute à operação e especificar o tipo Cat nesses atributos. Para saber mais, confira Tipos de contrato de dados conhecidos.

Para obter detalhes de como funciona a serialização polimórfica e uma discussão sobre algumas das limitações que devem ser respeitadas ao usá-la, consulte a seção Informações Avançadas mais adiante neste artigo.

Controle de versão

Os recursos de controle de versão do contrato de dados, incluindo a interface IExtensibleDataObject, têm suporte total no JSON. Além disso, na maioria dos casos, é possível desserializar um tipo em um formato (por exemplo, XML) e, em seguida, serializá-lo em outro formato (por exemplo, JSON) e ainda preservar os dados em IExtensibleDataObject. Para obter mais informações, consulte Contratos de dados compatíveis por encaminhamento. Lembre-se de que JSON não é ordenado para que qualquer informação de ordem seja perdida. Além disso, o JSON não dá suporte a vários pares chave/valor com o mesmo nome de chave. Por fim, todas as operações em IExtensibleDataObject são inerentemente polimórficas – ou seja, seu tipo derivado é atribuído a Object, o tipo base para todos os tipos.

JSON em URLs

Ao usar os pontos de extremidade ASP.NET AJAX com o verbo HTTP GET (usando o atributo WebGetAttribute), os parâmetros de entrada aparecem na URL da solicitação em vez de no corpo da mensagem. JSON é compatível mesmo na URL da solicitação, portanto, se você tiver uma operação que usa um Int chamado "número" e um tipo Person complexo chamado "p", a URL poderá ser semelhante à URL a seguir.

http://example.com/myservice.svc/MyOperation?number=7&p={"name":"John","age":42}

Se você estiver usando um controle e um proxy do Gerenciador de Scripts ASP.NET AJAX para chamar o serviço, essa URL será gerada automaticamente pelo proxy e não será vista. O JSON não pode ser usado em URLs em pontos de extremidade que não são ASP.NET AJAX.

Informações avançadas

Suporte ISerializable

Tipos ISerializable com suporte e sem suporte

Em geral, os tipos que implementam a interface ISerializable têm suporte total ao serializar/desserializar o JSON. No entanto, alguns desses tipos (incluindo alguns tipos de .NET Framework) são implementados de forma que os aspectos de serialização específicos de JSON fazem com que eles não desserializem corretamente:

  • Com ISerializable, o tipo de membros de dados individuais nunca é conhecido com antecedência. Isso leva a uma situação polimórfica semelhante à desserialização de tipos em um objeto. Conforme mencionado anteriormente, isso pode levar à perda de informações de tipo no JSON. Por exemplo, um tipo que serializa um enum em sua implementação ISerializable e tenta desserializar novamente diretamente em um enum (sem conversões adequadas) falha, pois um enum é serializado usando números em JSON e números JSON desserializam em tipos numéricos .NET internos (Int32, Decimal ou Double). Portanto, o fato de que o número usado para ser um valor enum é perdido.

  • Um tipo ISerializable que depende de uma ordem específica de desserialização em seu construtor de desserialização também pode falhar ao desserializar alguns dados JSON, pois a maioria dos serializadores JSON não garante nenhuma ordem específica.

Tipos de fábrica

Embora a interface IObjectReference tenha suporte no JSON em geral, não há suporte para todos os tipos que exigem o recurso "tipo de fábrica" (retornando uma instância de um tipo diferente de GetRealObject(StreamingContext) do que o tipo que implementa a interface).

Formato datetime wire

Os valores DateTime aparecem como cadeias de caracteres JSON na forma de "/Date(700000+0500)/", em que o primeiro número (700000 no exemplo fornecido) é o número de milissegundos no fuso horário GMT, horário regular (sem horário de verão) desde meia-noite de 1º de janeiro de 1970. O número pode ser negativo para representar horas anteriores. A parte que consiste em "+0500" no exemplo é opcional e indica que a hora é do tipo Local, ou seja, deve ser convertida no fuso horário local na desserialização. Se estiver ausente, o tempo será desserializado como Utc. O número real ("0500" neste exemplo) e seu sinal (+ ou -) são ignorados.

Ao serializar DateTime, Local e Unspecified, as horas são gravadas com um deslocamento e Utc é gravado sem.

O código JavaScript do cliente ASP.NET AJAX converte automaticamente essas cadeias de caracteres em instâncias JavaScript DateTime. Se houver outras cadeias de caracteres que tenham uma forma semelhante que não seja do tipo DateTime no .NET, elas também serão convertidas.

A conversão só ocorrerá se os caracteres "/" forem escapados (ou seja, o JSON se parecerá com "\/Date(700000+0500)\/") e, por esse motivo, o codificador JSON do WCF (habilitado pelo WebHttpBinding) sempre escapará do caractere "/".

XML em cadeias de caracteres JSON

XmlElement

XmlElement é serializado como está, sem quebra de linha. Por exemplo, o membro de dados "x" do tipo XmlElement que contém <abc/> é representado da seguinte maneira:

{"x":"<abc/>"}

Matrizes de XmlNode

Array os objetos do tipo XmlNode são encapsulados em um elemento chamado ArrayOfXmlNode no namespace de contrato de dados padrão para o tipo. Se "x" for uma matriz que contém o nó de atributo "N" no namespace "ns" que contém "value" e um nó de elemento vazio "M", a representação será a seguinte.

{"x":"<ArrayOfXmlNode xmlns=\"http://schemas.datacontract.org/2004/07/System.Xml\" a:N=\"value\" xmlns:a=\"ns\"><M/></ArrayOfXmlNode>"}

Atributos no namespace vazio no início de matrizes XmlNode (antes de outros elementos) não são compatíveis.

Tipos IXmlSerializable, incluindo XElement e DataSet

Os tipos ISerializable subdividem em "tipos de conteúdo", "Tipos de DataSet" e "tipos de elemento". Para obter definições desses tipos, consulte Tipos XML e ADO.NET em contratos de dados.

Os tipos "Content" e "DataSet" são serializados de forma semelhante aos objetos Array de XmlNode discutidos na seção anterior. Eles são encapsulados em um elemento cujo nome e namespace correspondem ao nome do contrato de dados e ao namespace do tipo em questão.

Tipos de "elemento", como XElement são serializados como estão, semelhantes ao XmlElement discutido anteriormente neste artigo.

Polimorfismo

Preservando informações de tipo

Conforme indicado anteriormente, o polimorfismo é suportado no JSON com algumas limitações. O JavaScript é uma linguagem de tipo fraco e a identidade de tipo normalmente não é um problema. No entanto, ao usar JSON para se comunicar entre um sistema de tipo forte (.NET) e um sistema de tipo fraco (JavaScript), é útil preservar a identidade do tipo. Por exemplo, tipos com nomes de contrato de dados "Square" e "Circle" derivam de um tipo com um nome de contrato de dados de "Shape". Se "Circle" for enviado do .NET para JavaScript e posteriormente for retornado para um método .NET que espera "Shape", será útil para o lado do .NET saber que o objeto em questão era originalmente um "Circle", caso contrário, qualquer informação específica para o tipo derivado (por exemplo, membro de dados "radius" em "Circle") pode ser perdida.

Para preservar a identidade do tipo, ao serializar tipos complexos para JSON, uma "dica de tipo" pode ser adicionada e o desserializador reconhece a dica e age adequadamente. A "dica de tipo" é um par de chave/valor JSON com o nome da chave "__type" (dois sublinhados seguidos pela palavra "type"). O valor é uma cadeia de caracteres JSON do formulário "DataContractName:DataContractNamespace" (qualquer coisa até os primeiros dois-pontos é o nome). Usando o exemplo anterior, "Circle" pode ser serializado da seguinte maneira.

{"__type":"Circle:http://example.com/myNamespace","x":50,"y":70,"radius":10}

A dica de tipo é muito semelhante ao atributo xsi:type definido pelo padrão da Instância de Esquema XML e usado ao serializar/desserializar o XML.

Os membros de dados chamados "__type" são proibidos devido a um possível conflito com a dica de tipo.

Reduzindo o tamanho das dicas de tipo

Para reduzir o tamanho das mensagens JSON, o prefixo de namespace do contrato de dados padrão (http://schemas.datacontract.org/2004/07/) é substituído pelo caractere "#". (Para tornar essa substituição reversível, uma regra de escape será usada: se o namespace começar com os caracteres "#" ou "\", eles serão acrescentados com um caractere "\"extra). Portanto, se "Circle" for um tipo no namespace do .NET "MyApp.Shapes", seu namespace de contrato de dados padrão será http://schemas.datacontract.org/2004/07/MyApp. As formas e a representação do JSON são as seguintes.

{"__type":"Circle:#MyApp.Shapes","x":50,"y":70,"radius":10}

Os nomes truncados (#MyApp.Shapes) e completos (http://schemas.datacontract.org/2004/07/MyApp.Shapes) são compreendidos na desserialização.

Posição da dica de tipo em objetos JSON

Observe que a dica de tipo deve aparecer primeiro na representação JSON. Esse é o único caso em que a ordem dos pares chave/valor é importante no processamento de JSON. Por exemplo, o seguinte não é uma maneira válida de especificar a dica de tipo.

{"x":50,"y":70,"radius":10,"__type":"Circle:#MyApp.Shapes"}

DataContractJsonSerializer usado pelo WCF e pelas páginas de cliente ASP.NET AJAX sempre emitem a dica de tipo primeiro.

Dicas de tipo aplicam-se somente a tipos complexos

Não há como emitir uma dica de tipo para tipos não complexos. Por exemplo, se uma operação tiver um tipo de retornoObject, mas retornar um Circle, a representação JSON poderá ser conforme mostrado anteriormente e as informações de tipo serão preservadas. No entanto, se Uri for retornado, a representação JSON será uma cadeia de caracteres e o fato da cadeia de caracteres ser usada para representar um Uri será perdido. Isso se aplica não apenas a tipos primitivos, mas também a coleções e matrizes.

Quando as dicas de tipo são emitidas

Dicas de tipo podem aumentar significativamente o tamanho da mensagem (uma maneira de atenuar isso é usar namespaces de contrato de dados mais curtos, se possível). Portanto, as seguintes regras regem se as dicas de tipo forem emitidas:

  • Ao usar ASP.NET AJAX, as dicas de tipo sempre são emitidas sempre que possível, mesmo que não haja nenhuma atribuição base/derivada, por exemplo, mesmo que um Circle seja atribuído a um Circle. (Isso é necessário para habilitar totalmente o processo de chamada do ambiente JSON de tipo fraco para o ambiente .NET de tipo forte sem perda surpreendente de informações.)

  • Ao usar serviços AJAX sem integração ASP.NET, as dicas de tipo só são emitidas quando há uma atribuição base/derivada, ou seja, emitida quando Circle é atribuído a Shape ou Object, mas não quando atribuído a Circle. Isso fornece as informações mínimas necessárias para implementar corretamente um cliente JavaScript, melhorando o desempenho, mas não protege contra perda de informações de tipo em clientes projetados incorretamente. Evite atribuições base/derivadas completamente no servidor se quiser evitar lidar com esse problema no cliente.

  • Ao usar o tipo DataContractSerializer, o parâmetro de constructo alwaysEmitTypeInformation permite que você escolha entre os dois modos anteriores, com o padrão sendo "false" (apenas emita dicas de tipo quando necessário).

Nomes de membros de dados duplicados

Informações de tipo derivado estão presentes no mesmo objeto JSON junto com informações de tipo base e podem ocorrer em qualquer ordem. Por exemplo, Shape pode ser representado da seguinte maneira.

{"__type":"Shape:#MyApp.Shapes","x":50,"y":70}

Enquanto Circle pode ser representado da seguinte maneira.

{"__type":"Circle:#MyApp.Shapes","x":50, "radius":10,"y":70}

Se o tipo base Shape também contiver um membro de dados chamado "radius", isso leva a uma colisão na serialização (porque os objetos JSON não podem ter nomes de chave recorrentes) e desserialização (porque não está claro se "radius" se refere a Shape.radius ou Circle.radius). Portanto, embora o conceito de "ocultação de propriedade" (membros de dados com o mesmo nome em classes baseadas e derivadas) geralmente não seja recomendado em classes de contrato de dados, ele é realmente proibido no caso de JSON.

Tipos polimorfismo e IXmlSerializable

Os tipos IXmlSerializable podem ser atribuídos polimorficamente uns aos outros, desde que os requisitos de Tipos Conhecidos sejam atendidos, de acordo com as regras usuais do contrato de dados. No entanto, serializar um tipo IXmlSerializable no lugar de Object resulta na perda de informações de tipo, pois o resultado é uma cadeia de caracteres JSON.

Polimorfismo e determinados tipos de interface

É proibido serializar um tipo de coleção ou um tipo que implementa IXmlSerializable, onde um tipo de não coleção, que não seja IXmlSerializable (exceto para Object), é esperado. Por exemplo, uma interface personalizada chamada IMyInterface e um tipo MyType que implementam o IEnumerable<T> de tipo int e IMyInterface. É proibido retornar MyType de uma operação cujo tipo de retorno é IMyInterface. Isso ocorre porque MyType deve ser serializado como uma matriz JSON e requer uma dica de tipo e, conforme indicado antes, você não pode incluir uma dica de tipo com matrizes, somente com tipos complexos.

Tipos conhecidos e configuração

Todos os mecanismos de Tipo Conhecido usados pelo DataContractSerializer também têm suporte da mesma forma pelo DataContractJsonSerializer. Ambos os serializadores leem o mesmo elemento de configuração, <dataContractSerializer> em <system.runtime.serialization>, para descobrir tipos conhecidos adicionados por meio de um arquivo de configuração.

Coleções atribuídas ao objeto

Coleções atribuídas a Objeto são serializadas como se fossem coleções que implementam IEnumerable<T>: uma matriz JSON com cada entrada que tem uma dica de tipo se for um tipo complexo. Por exemplo, um List<T> tipo Shape atribuído a Object se parece com o seguinte.

[{"__type":"Shape:#MyApp.Shapes","x":50,"y":70},
{"__type":"Shape:#MyApp.Shapes","x":58,"y":73},
{"__type":"Shape:#MyApp.Shapes","x":41,"y":32}]

Quando desserializado novamente em Object:

  • Shape deve estar na lista de Tipos Conhecidos. Ter List<T> do tipo Shape em tipos conhecidos não tem efeito. Observe que você não precisa adicionar Shape a tipos conhecidos sobre serialização nesse caso – isso é feito automaticamente.

  • A coleção é desserializada como um Array de tipo Object que contém Shape instâncias.

Coleções derivadas atribuídas a coleções base

Quando uma coleção derivada é atribuída a uma coleção base, a coleção geralmente é serializada como se fosse uma coleção do tipo base. No entanto, se o tipo de item da coleção derivada não puder ser atribuído ao tipo de item da coleção base, uma exceção será gerada.

Dicas de tipo e dicionários

Quando um dicionário é atribuído a Object, cada entrada Key e Value no dicionário é tratada como se tivesse sido atribuída a Object e obtém uma dica de tipo.

Ao serializar tipos de dicionário, o objeto JSON que contém os membros "Key" e "Value" não é afetado pela configuração alwaysEmitTypeInformation e contém apenas uma dica de tipo quando as regras de coleção anteriores exigirem isso.

Nomes de chave JSON válidos

O serializador XML codifica nomes de chave que não são nomes XML válidos. Por exemplo, um membro de dados com o nome "123" teria um nome codificado como "_x0031__x0032__x0033_" porque "123" é um nome de elemento XML inválido (começa com um dígito). Uma situação semelhante pode surgir com alguns conjuntos de caracteres internacionais não válidos em nomes XML. Para obter uma explicação desse efeito de XML no processamento JSON, consulte Mapeamento entre JSON e XML.

Confira também