Compartir a través de


Presentar la serialización XML

La serialización es el proceso de convertir un objeto de forma que pueda transportarse fácilmente. Por ejemplo, puede serializar un objeto y transportarlo por Internet utilizando HTTP entre un cliente y un servidor. En el otro extremo, la deserialización reconstruye el objeto a partir de la secuencia.

La serialización XML sólo serializa los campos públicos y los valores de propiedad de un objeto en una secuencia XML. No incluye información de los tipos. Por ejemplo, si un objeto Book existe en el espacio de nombres Library, no hay ninguna garantía de que se deserialice en un objeto del mismo tipo.

Nota   La serialización XML no convierte los métodos, indizadores, campos privados ni propiedades de sólo lectura (salvo colecciones de sólo lectura). Para serializar todos los campos y propiedades, tanto públicos como privados, de un objeto, utilice BinaryFormatter en lugar de la serialización XML.

La clase central de la serialización XML es XmlSerializer y sus métodos más importantes son Serialize y Deserialize. La secuencia XML que genera XmlSerializer cumple con la recomendación 1.0 del W3C (www.w3.org) acerca del lenguaje de definición de esquemas XML (XSD). Además, los tipos de datos generados cumplen las especificaciones enumeradas en el documento titulado "XML Schema Part 2: Datatypes".

Los datos de los objetos se describen utilizando construcciones de lenguaje de programación como clases, campos, propiedades, tipos primitivos, matrices e incluso XML incrustado en forma de objetos XmlElement o XmlAttribute. Puede crear clases propias, anotadas con atributos, o utilizar la herramienta Definición de esquemas XML para generar las clases de acuerdo con un esquema XML existente.

Si dispone de un esquema XML, puede ejecutar la herramienta Definición de esquemas XML con el fin de generar un conjunto de clases con establecimiento inflexible de tipos para el esquema y anotarlas con atributos. Cuando se serializa una instancia de dicha clase, el XML generado se ajusta al esquema XML. Con esa clase puede programar con respecto a un modelo de objeto fácilmente manipulado al tiempo que se asegura de que el XML generado se adecua al esquema XML. Se trata de una alternativa a la utilización de otras clases de .NET Framework, como XmlReader y XmlWriter, para analizar y escribir una secuencia XML. Para obtener más información sobre cómo usar esas clases, vea Emplear XML en .NET Framework. Esas clases permiten analizar cualquier secuencia XML. Por el contrario, utilice la clase XmlSerializer cuando la secuencia XML deba ajustarse a un esquema XML conocido.

Los atributos controlan la secuencia XML que genera la clase XmlSerializer y le permiten establecer el espacio de nombres XML, nombre de elemento, nombre de atributo, etcétera, de la secuencia XML. Para obtener más información acerca de estos atributos y de cómo controlan la serialización XML, vea Controlar la serialización XML mediante atributos. Para obtener una tabla de los atributos utilizados para controlar el XML generado, vea Atributos que controlan la serialización XML.

La clase XmlSerializer puede serializar más un objeto y generar una secuencia XML SOAP codificada. El XML generado se ajusta a las especificaciones de la sección 5 del documento del W3C titulado "Simple Object Access Protocol (SOAP) 1.1". Para obtener más información acerca de este proceso, vea Generar mensajes SOAP con serialización XML. Para obtener una tabla de los atributos que controlan el XML generado, vea Atributos que controlan la serialización SOAP codificada.

La clase XmlSerializer genera los mensajes SOAP pasados a los servicios Web XML o creados por ellos. Para controlar los mensajes SOAP, puede aplicar atributos a las clases, valores devueltos, parámetros y campos encontrados en un archivo de servicio Web XML (.asmx). Puede utilizar los atributos enumerados en "Atributos que controlan la serialización XML" y en "Atributos que controlan la serialización SOAP codificada" porque un servicio Web XML puede utilizar el estilo SOAP literal o codificado. Para obtener más información sobre cómo usar atributos para controlar el XML que genera un servicio Web XML, vea Serialización XML con servicios Web XML. Para obtener más información acerca de los servicios Web XML y SOAP, vea Personalizar mensajes SOAP.

Proteger aplicaciones que utilizan la clase XmlSerializer

Al crear una aplicación que utiliza la clase XmlSerializer, debe tener en cuenta los siguientes elementos y sus implicaciones:

  • La clase XmlSerializer crea archivos de C# (archivos .cs) y los compila en archivos .dll en el directorio especificado por la variable de entorno TEMP; la serialización se produce con esos archivos DLL.

    El código y los archivos DLL son vulnerables a un proceso malicioso en el momento de la creación y de la compilación. Si se utiliza un equipo que ejecuta Microsoft Windows NT 4.0 o superior, el directorio temp puede estar compartido por dos o más usuarios. Compartir el directorio temp es peligroso si (1) las dos cuentas tienen privilegios de seguridad diferentes, y (2) la cuenta con más privilegios ejecuta una aplicación que utiliza la clase XmlSerializer. En este caso, un usuario puede poner en peligro la seguridad del equipo si reemplaza el archivo .cs o el archivo .dll compilado. Para eliminar este problema, compruebe siempre que cada cuenta del equipo tiene su propio perfil. Si es así, la variable de entorno TEMP señalará, de forma predeterminada, a un directorio diferente para cada cuenta.

  • Si un usuario malintencionado envía una secuencia continua de datos XML a un servidor Web (ataque de denegación de servicio), entonces la clase XmlSerializer seguirá procesando datos hasta que el equipo no disponga de suficientes recursos.

    Este tipo de ataque se elimina si se utiliza un equipo en el que se ejecuten los Servicios de Internet Information Server (IIS), y si la aplicación se ejecuta dentro de IIS. IIS ofrece una puerta que no procesa las secuencias que sean más largas que el valor establecido (el valor predeterminado es 4 KB). Si crea una aplicación que no utiliza IIS y que se deserializa con XmlSerializer, deberá implementar una puerta similar para impedir los ataques de denegación de servicio.

  • La clase XmlSerializer serializa los datos y ejecuta cualquier código que utilice el tipo proporcionado.

    Hay dos casos en los que un objeto malicioso representa una amenaza. Si puede ejecutar código malicioso o puede insertar código malicioso en el archivo de C# creado con la clase XmlSerializer. En el primer caso, si un objeto malicioso intenta ejecutar un procedimiento destructivo, la seguridad de acceso a código impedirá que se haga cualquier daño. En el segundo caso, existe la posibilidad hipotética de que un objeto malicioso inserte de alguna manera código en el archivo C# creado mediante la clase XmlSerializer. Aunque este problema se ha examinado a fondo, y este tipo de ataque se considera sumamente remoto, se debe tomar la precaución de no serializar nunca los datos con un tipo desconocido o que no sea de confianza.

  • Los datos confidenciales serializados pueden ser vulnerables.

    Una vez que la clase XmlSerializer ha serializado los datos, se pueden guardar en un archivo XML u otro almacén de datos. Si el almacén de datos está disponible para otros procesos, o está visible en una intranet o en Internet, los datos pueden ser robados y se pueden utilizar con malas intenciones. Por ejemplo, los datos de una aplicación que serializa pedidos que incluyen números de tarjetas de crédito son extremadamente confidenciales. Para impedir esto, proteja siempre el almacén de datos y manténgalo privado.

Serialización de una clase simple

En el ejemplo siguiente se muestra una clase simple con un campo público:

Public Class OrderForm
    Public OrderDate As DateTime
End Class
[C#]
public class OrderForm{
    public DateTime OrderDate;
}

Cuando se serializa una instancia de esta clase, puede parecerse a lo siguiente:

<OrderForm>
    <OrderDate>12/12/01</OrderDate>
</OrderForm>

Para obtener más ejemplos de serialización, vea Ejemplos de serialización XML.

Elementos que pueden serializarse

Los elementos siguientes pueden serializarse utilizando la clase XmLSerializer.

  • Propiedades públicas de lectura y escritura, y campos de clases públicas
  • Clases que implementan ICollection o IEnumerable (tenga en cuenta que sólo se serializan las colecciones, no las propiedades públicas)
  • Objetos XmlElement
  • Objetos XmlNode
  • Objetos DataSet

Serializar y deserializar objetos

Para serializar un objeto, primero cree el objeto que se va a serializar y establezca sus propiedades y campos públicos. Para ello, debe determinar el formato de transporte en el que se almacenará la secuencia XML (como secuencia o como archivo). Por ejemplo, si la secuencia XML debe guardarse de forma permanente, cree un objeto FileStream. Cuando deserializa un objeto, el formato de transporte determina si se creará un objeto de secuencia o de archivo. Una vez determinado el formato de transporte, puede llamar a los métodos Serialize o Deserialize, según corresponda.

Para serializar un objeto

  1. Cree el objeto y establezca sus campos y propiedades públicos.

  2. Construya un XmlSerializer con el tipo del objeto. Para obtener más información, vea los constructores de la clase XmlSerializer.

  3. Llame al método Serialize para generar una secuencia XML o una representación de archivo de los campos y propiedades públicos del objeto. En el ejemplo siguiente se crea un archivo.

    Dim myObject As MySerializableClass = New MySerializableClass()
    ' Insert code to set properties and fields of the object.
    Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(MySerializableClass))
    ' To write to a file, create a StreamWriter object.
    Dim myWriter As StreamWriter = New StreamWriter("myFileName.xml")
    mySerializer.Serialize(myWriter, myObject)
    
    [C#]
    MySerializableClass myObject = new MySerializableClass();
    // Insert code to set properties and fields of the object.
    XmlSerializer mySerializer = new 
    XmlSerializer(typeof(MySerializableClass));
    // To write to a file, create a StreamWriter object.
    StreamWriter myWriter = new StreamWriter("myFileName.xml");
    mySerializer.Serialize(myWriter, myObject);
    

Para deserializar un objeto

  1. Construya un XmlSerializer con el tipo del objeto que se va a deserializar.

  2. Llame al método Deserialize para producir un replicado del objeto. Al deserializar, debe convertir el objeto devuelto al tipo del original, como se muestra a continuación. En el ejemplo siguiente se deserializa el objeto en un archivo, aunque también puede deserializarse en una secuencia.

    Dim myObject As MySerializableClass
    ' Constructs an instance of the XmlSerializer with the type
    ' of object that is being deserialized.
    Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(MySerializableClass))
    ' To read the file, creates a FileStream.
    Dim myFileStream As FileStream = _
    New FileStream("myFileName.xml", FileMode.Open)
    ' Calls the Deserialize method and casts to the object type.
    myObject = CType( _
    mySerializer.Deserialize(myFileStream), MySerializableClass)
    [C#]
    MySerializableClass myObject;
    // Constructs an instance of the XmlSerializer with the type
    // of object that is being deserialized.
    XmlSerializer mySerializer = 
    new XmlSerializer(typeof(MySerializableClass));
    // To read the file, creates a FileStream.
    FileStream myFileStream = 
    new FileStream("myFileName.xml", FileMode.Open);
    // Calls the Deserialize method and casts to the object type.
    myObject = (MySerializableClass) 
    mySerializer.Deserialize(myFileStream)
    

Para obtener más ejemplos de serialización XML, vea Ejemplos de serialización XML.

Ventajas de utilizar la serialización XML

La clase XmlSerializer ofrece un control total y flexible al serializar un objeto como XML. Si está creando un servicio Web XML, puede aplicar atributos que controlen la serialización para clases y miembros a fin de garantizar que el resultado XML se ajuste a un esquema específico.

Por ejemplo, XmlSerializer permite:

  • Especificar si un campo o una propiedad debe codificarse como un atributo o un elemento.
  • Especificar el espacio de nombres XML que se va a utilizar.
  • Especificar el nombre de un elemento o atributo si un nombre de campo o de propiedad es inapropiado.

Otra de las ventajas de la serialización XML es que no tiene restricciones en las aplicaciones que se desarrollen, siempre que la secuencia XML que se genere se ajuste a un esquema determinado. Imagine un esquema utilizado para describir libros (incluye un elemento de título, autor, editor y número ISBN). Puede desarrollar una aplicación que procese los datos XML del modo que desee (por ejemplo, como pedido o como inventario de libros). En cualquier caso, el único requisito es que la secuencia XML se ajuste al esquema de lenguaje XSD especificado.

Consideraciones de la serialización XML

Al utilizar la clase XmLSerializer debe considerarse lo siguiente:

  • Los datos serializados contienen únicamente los datos y la estructura de las clases. No incluyen ni la identidad de tipo ni la información de ensamblado.
  • Sólo se pueden serializar los campos y propiedades públicos. Si necesita serializar datos que no sean públicos, utilice la clase BinaryFormatter en lugar de la serialización XML.
  • Una clase debe tener un constructor predeterminado para que XmlSerializer la serialice.
  • Los métodos no se pueden serializar.
  • XmlSerializer puede procesar clases que implementen IEnumerable o ICollection de forma distinta si cumplen ciertos requisitos. Una clase que implementa IEnumerable debe implementar un método Add público que acepte un solo parámetro. El parámetro del método Add debe ser coherente (polimórfico) con el tipo devuelto de la propiedad IEnumerator.Current devuelta del método GetEnumerator. Una clase que implementa ICollection además de IEnumerable (por ejemplo, CollectionBase) debe tener una propiedad Item indizada y pública (indizador en C#) que acepte un entero y una propiedad Count pública de tipo entero. El parámetro pasado al método Add debe ser del mismo tipo que el devuelto por la propiedad Item o una de las bases de dicho tipo. Para las clases que implementan ICollection, los valores que se van a serializar se recuperarán de la propiedad Item indizada en lugar de con una llamada a GetEnumerator. Asimismo, observe que los campos y propiedades públicos no se serializarán, a excepción de los campos públicos que devuelvan otra clase de colección (una que implemente ICollection). Para obtener un ejemplo, vea Ejemplos de serialización XML.

Asignación de tipos de datos XSD

En el documento del W3C (www.W3.org) titulado "XML Schema Part 2: Datatypes" se especifican los tipos de datos simples que se permiten en un esquema de lenguaje de definición de esquemas XML (XSD). Para muchos de ellos (por ejemplo, int y decimal), hay un tipo de dato correspondiente en .NET Framework. No obstante, algunos tipos de datos XML no tienen un tipo correspondiente en Framework (por ejemplo, el tipo de datos NMTOKEN). En esos casos, si utiliza la herramienta Definición de esquemas XML (Xsd.exe) para generar clases a partir de un esquema, se aplica un atributo apropiado a un miembro de cadena de tipo y el nombre del tipo de datos XML se establece como valor de su propiedad DataType. Por ejemplo, si un esquema contiene un elemento denominado "MyToken" con el tipo de datos XML NMTOKEN, la clase generada puede contener un miembro, como se muestra en el ejemplo siguiente.

<XmlElement(DataType:="NMTOKEN")>
Public MyToken As String
[C#]
[XmlElement(DataType = "NMTOKEN")]
public string MyToken;

De igual modo, si está creando una clase que debe ajustarse a un esquema XML específico (XSD), debe aplicar el atributo apropiado y establecer el nombre del tipo de datos XML deseado como valor de la propiedad DataType.

Para obtener una lista completa de las asignaciones de tipos, vea la propiedad DataType de las siguientes clases de atributo: SoapAttributeAttribute, SoapElementAttribute, XmlArrayItemAttribute, XmlAttributeAttribute, XmlElementAttribute o XmlRootAttribute.

Vea también

Serialización XML y SOAP | XMLSerializer.Serialize | BinaryFormatter | Serialización binaria | Serializar objetos | XmlSerializer | FileStream | Ejemplos de serialización XML