Utilización de la clase XmlSerializer

Windows Communication Foundation (WCF) puede utilizar dos tecnologías de serialización diferentes para convertir los datos de su aplicación en XML transmitidos entre los clientes y servicios, un proceso llamado serialización.

DataContractSerializer como predeterminado

De forma predeterminada WCF utiliza la clase DataContractSerializer para serializar los tipos de datos. Este serializador admite los tipos siguientes:

  • Tipos primitivos (por ejemplo, enteros, cadenas y matrices de bytes), así como algunos tipos especiales, como XmlElement y DateTime, que se tratan como primitivos.
  • Tipos de contrato de datos (los tipos marcados con el atributo DataContractAttribute ).
  • Los tipos marcados con el atributo SerializableAttribute, incluidos los tipos que implementan la interfaz ISerializable.
  • Los tipos que implementan la interfaz IXmlSerializable.
  • Muchos tipos de colección comunes, que incluyen muchos tipos de colección genéricos.

Muchos tipos .NET Framework se incluyen en las dos últimas categorías y son, de este modo, serializables. Las matrices de tipos serializables también son serializables. Para obtener una lista completa, consulte Especificación de transferencia de datos en contratos de servicio.

DataContractSerializer, utilizado junto con los tipos de contrato de datos, es la manera recomendada de escribir nuevos servicios WCF. Para obtener más información, consulte Utilización de contratos de datos.

Cuándo utilizar la clase XmlSerializer

WCF también admite la clase XmlSerializer. La clase XmlSerializer es no es exclusiva de WCF. Es el mismo motor de serialización que usan los servicios web de ASP.NET. La clase XmlSerializer admite un conjunto mucho más estrecho de tipos que la clase DataContractSerializer, pero permite mucho más control sobre el XML resultante y admite mucho más de la norma del lenguaje de definición de esquemas XML (XSD). Tampoco requiere ningún atributo declarativo en los tipos serializables. Para obtener más información, consulte el tema de la Serialización XML en la documentación .NET Framework. La clase XmlSerializer no admite tipos de contrato de datos.

Cuando se utiliza Svcutil.exe o la característica Agregar referencia de servicio en Visual Studio para generar el código de cliente para un servicio de otro fabricante o para tener acceso a un esquema de otro fabricante, se selecciona automáticamente un serializador adecuado para usted. Si el esquema no es compatible con DataContractSerializer, se selecciona el XmlSerializer.

Intercambio manual a XmlSerializer

En algunas ocasiones, puede ser necesario intercambiar manualmente a XmlSerializer. Esto sucede, por ejemplo, en los casos siguientes:

  • Al migrar una aplicación desde los servicios Web ASP.NET a WCF, usted puede querer reutilizar los tipos compatibles existentes, XmlSerializer- en lugar de crear nuevos tipos de contrato de datos.
  • Cuando es importante el control preciso sobre el XML que aparece en los mensajes, pero no hay disponible un documento de lenguaje de descripción de servicios web (WSDL), por ejemplo, al crear un servicio con tipos que tienen que cumplir un cierto esquema normalizado, publicado, no compatible con DataContractSerializer.
  • Al crear servicios que siguen la norma de Codificación SOAP heredada.

En éstos y otros casos, puede intercambiar manualmente a la clase XmlSerializer aplicando el atributo XmlSerializerFormatAttribute a su servicio, tal y como se muestra en el código siguiente.

Consideraciones de seguridad

Nota

Es importante tener el cuidado al intercambiar los motores de serialización. El mismo tipo puede serializar de maneras diferentes, dependiendo del serializador que se utiliza. Si por error utiliza un serializador erróneo, podría estar divulgando información de un tipo que no tenía intención de divulgar.

Por ejemplo, la clase DataContractSerializer sólo serializa los miembros marcados con el atributo DataMemberAttribute al serializar los tipos de contrato de datos. La clase XmlSerializer serializa cualquier miembro público. Vea el tipo del código siguiente.

Si el tipo se utiliza inadvertidamente en un contrato de servicios donde está seleccionada la clase XmlSerializer, se serializa el miembro creditCardNumber que probablemente no corresponde.

Aunque la clase DataContractSerializer es el valor predeterminado, puede seleccionarlo explícitamente para su servicio (aunque esto no se debería exigir nunca) aplicando el atributo DataContractFormatAttribute al tipo de contrato de servicios.

El serializador utilizado para el servicio es una parte integrante del contrato y no se puede cambiar seleccionando un enlace diferente o cambiando otra configuración.

Otras consideraciones de seguridad importantes se aplican a la clase XmlSerializer. En primer lugar, se recomienda encarecidamente firmar las aplicaciones WCF que utiliza la clase XmlSerializer con una clave protegida contra la divulgación. Esta recomendación se aplica cuando se realiza un modificador manual a XmlSerializer y cuando se lleva a cabo un modificador automático (mediante Svcutil.exe, Agregar referencia de servicio o una herramienta similar). Esto es debido a que el motor de serialización XmlSerializer admite la carga de ensamblados de serialización pregenerados siempre que se firmen con la misma clave que la aplicación. Una aplicación sin firma está totalmente desprotegida frente a la posibilidad de que un ensamblado malintencionado que coincida con el nombre esperado del ensamblado de serialización previamente generado se sitúe en la carpeta de aplicaciones o en la caché de ensamblados global. Por supuesto, antes de nada, un atacante debe tener acceso de escritura a una de estas dos ubicaciones para intentar realizar dicha acción.

Otra amenaza que existe siempre que usted utiliza XmlSerializer está relacionada con el acceso de escritura a la carpeta temporal del sistema. El motor de serialización XmlSerializer crea y utiliza ensamblados de serialización temporales en esta carpeta. Debería ser consciente de que cualquier proceso con acceso de escritura a la carpeta temporal puede sobrescribir estos ensamblados de serialización con código malintecionado.

Reglas para la compatibilidad de XmlSerializer

No puede aplicar directamente XmlSerializer- los atributos compatibles a los parámetros de operación de contrato o valores devueltos. Sin embargo, se pueden aplicar a los mensajes con tipo (partes del cuerpo del contrato de mensaje), como se muestra en el código siguiente.

Cuando se aplica a los miembros de mensaje con tipo, estos atributos invalidan propiedades que están en conflicto en los atributos de mensaje con tipo. Por ejemplo en el siguiente código, ElementName invalida Name.

No se admite el atributo MessageHeaderArrayAttribute al utilizar XmlSerializer.

Nota

En este caso, XmlSerializer inicia la excepción siguiente, que se libera antes que WCF: "El elemento declarado en el nivel superior de un esquema no puede tener maxOccurs >1. Debe proporcionar un elemento contenedor para 'más' utilizando XmlArray o XmlArrayItem en lugar de XmlElementAttribute o utilizando el estilo de parámetro Wrapped".

Si recibe esta excepción, investigue si se aplica esta situación.

WCF no admite SoapIncludeAttribute ni atributos XmlIncludeAttribute en contratos de mensaje y contratos de operación; utilice, en su lugar, el atributo KnownTypeAttribute.

Consulte también

Tareas

Cómo: Mejorar el tiempo de inicio de las aplicaciones cliente WCF mediante XmlSerializer

Referencia

DataContractFormatAttribute
DataContractSerializer
XmlSerializer
MessageHeaderArrayAttribute

Conceptos

Especificación de transferencia de datos en contratos de servicio
Utilización de contratos de datos