Compartir a través de


Serialización y metadatos

Si la aplicación serializa y deserializa objetos, es posible que deba agregar entradas al archivo de directivas en tiempo de ejecución (.rd.xml) para asegurarse de que los metadatos necesarios están presentes en tiempo de ejecución. Existen dos categorías de serializadores y cada una requiere un tratamiento distinto en el archivo de directivas en tiempo de ejecución:

  • Serializadores de terceros basados en la reflexión. Estos requieren modificaciones en el archivo de directivas en tiempo de ejecución y se describen en la sección siguiente.

  • Serializadores no basados en reflexión que se encuentran en la biblioteca de clases de .NET Framework. Estos pueden exigir modificaciones en el archivo de directivas en tiempo de ejecución, y se explican en la sección Serializadores de Microsoft.

Serializadores de terceros

Los serializadores de terceros, incluidos los Newtonsoft.JSON, normalmente se basan en la reflexión. Dado un objeto binario grande (BLOB) de datos serializados, los campos de los datos se asignan a un tipo concreto mediante la búsqueda por nombre de los campos del tipo de destino. Como mínimo, el empleo de estas bibliotecas produce excepciones MissingMetadataException para cada objeto Type que se intenta serializar o deserializar en una colección List<Type>.

La forma más sencilla de solucionar los problemas causados por la falta de metadatos para estos serializadores es recopilar los tipos que se utilizarán en la serialización en un único espacio de nombres (como App.Models) y aplicar una directiva de metadatos Serialize:

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

Para obtener información sobre la sintaxis usada en el ejemplo, vea <Namespace> Element.

Serializadores de Microsoft

Aunque las clases DataContractSerializer, DataContractJsonSerializer y XmlSerializer no se basan en la reflexión, necesitan generar código en función del objeto que se va a serializar o deserializar. Los constructores sobrecargados de cada serializador incluyen un parámetro Type que especifica el tipo que se va a serializar o deserializar. La forma de especificar ese tipo en el código define la acción que se debe realizar, como se explica en las dos secciones siguientes.

typeof utilizado en el constructor

Si llama a un constructor de estas clases de serialización e incluye el operador typeof de C# en la llamada al método, no tiene que realizar ningún trabajo adicional. Por ejemplo, en cada una de las siguientes llamadas a un constructor de clase de serialización, la palabra clave typeof se utiliza como parte de la expresión que se pasa al constructor.

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

El compilador de .NET Native controlará automáticamente este código.

typeof usado fuera del constructor

Si llama a un constructor de estas clases de serialización y usa el operador typeof de C# fuera de la expresión proporcionada al parámetro del Type constructor, como en el código siguiente, el compilador de .NET Native no puede resolver el tipo:

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

En este caso, debe especificar el tipo en el archivo de directivas de tiempo de ejecución mediante la adición de una entrada como la siguiente:

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

Del mismo modo, si llama a un constructor como XmlSerializer(Type, Type[]) y proporciona una matriz de objetos adicionales Type para serializar, como en el código siguiente, el compilador de .NET Native no puede resolver estos tipos.

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

Agregue entradas como las siguientes para cada tipo al archivo de directivas en tiempo de ejecución:

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

Para obtener información sobre la sintaxis usada en el ejemplo, vea <Type> Element.

Consulte también