Compartilhar via


Serialização e metadados

Se seu aplicativo serializa ou desserializa objetos, talvez seja necessário adicionar entradas aos seus arquivos de diretivas de runtime (.rd.xml) para garantir que os metadados necessários estejam presentes no runtime. Há duas categorias de serializadores e cada uma necessita de um tratamento diferente no arquivo de diretivas de runtime:

  • Serializadores de terceiros baseados em reflexão. Eles necessitam de modificações no arquivo de diretivas de runtime e são discutidos na próxima seção.

  • Serializadores não baseados em reflexão encontrados na biblioteca de classes do .NET Framework. Eles podem necessitar de modificações no arquivo de diretivas de runtime e são discutidos na seção Serializadores da Microsoft.

Serializadores de terceiros

Os serializadores de terceiros, incluindo Newtonsoft.JSON, normalmente são baseados em reflexão. Dado um BLOB (objeto binário grande) de dados serializados, os campos nos dados são atribuídos a um tipo concreto examinando os campos do tipo de destino por nome. No mínimo, usar essas bibliotecas causa exceções MissingMetadataException para cada objeto Type que você tentar serializar ou desserializar em uma coleção List<Type>.

A maneira mais fácil para solucionar problemas causados pela falta de metadados para esses serializadores é coletar tipos que serão usados na serialização de um único namespace (como App.Models) e aplicar uma diretiva de metadados Serialize a ele:

<Namespace Name="App.Models" Serialize="Required PublicAndInternal" />

Para obter informações sobre a sintaxe usada no exemplo, consulte <Elemento de namespace>.

Serializadores da Microsoft

Embora as classes DataContractSerializer, DataContractJsonSerializer e XmlSerializer não dependam de reflexão, elas necessitam que o código seja gerado com base no objeto a ser serializado ou desserializado. Os construtores sobrecarregados para cada serializador incluem um parâmetro Type que especifica o tipo a ser serializado ou desserializado. A maneira como este tipo é especificado no código define a ação que deve ser tomada, conforme discutido nas duas próximas seções.

typeof usado no construtor

Se você chamar um construtor dessas classes de serialização e incluir o operador typeof do C# na chamada do método, não precisará fazer nenhum trabalho adicional. Por exemplo, em cada uma das seguintes chamadas para um construtor de classe de serialização, a palavra-chave typeof é usada como parte da expressão passada para o construtor.

XmlSerializer xmlSer = new XmlSerializer(typeof(T));
DataContractSerializer dataSer = new DataContractSerializer(typeof(T));
DataContractJsonSerializer jsonSer = new DataContractJsonSerializer(typeof(T));

O compilador .NET Native manipulará automaticamente esse código.

typeof usado fora do construtor

Se você chamar um construtor dessas classes de serialização e usar o operador typeof do C# fora da expressão fornecida ao parâmetro do Type construtor, como no código a seguir, o compilador do .NET Native não poderá resolver o tipo:

Type t = typeof(DataSet);
XmlSerializer ser = new XmlSerializer(t);

Nesse caso, você deve especificar o tipo do arquivo de diretivas de runtime adicionando uma entrada como esta:

<Type Name="DataSet" Browse="Required Public" />

Da mesma forma, se você chamar um construtor como XmlSerializer(Type, Type[]) e fornecer uma matriz de objetos adicionais Type para serializar, como no código a seguir, o compilador .NET Native não poderá resolver esses tipos.

XmlSerializer xSerializer = new XmlSerializer(typeof(Teacher),
                            new Type[] { typeof(Student),
                                         typeof(Course),
                                         typeof(Location) });

Adicione entradas como as seguintes para cada tipo ao arquivo de diretivas de tempo de execução:

<Type Name="t" Browse="Required Public" />

Para obter informações sobre a sintaxe usada no exemplo, consulte <Elemento de tipo>.

Confira também