xmlelementattribute xmlelement xmlattribute net example deserialize .net xml serialization

.net - xmlattribute - xmlelement c#



Usando.Net, ¿qué limitaciones(si existen) existen al usar XmlSerializer? (8)

Usando .Net, ¿qué limitaciones (si existen) existen al usar XmlSerializer? Por ejemplo, ¿puede serializar Imágenes a XML?


Cualquier clase que escriba se puede alimentar teóricamente a través de XmlSerializer. Howerver, solo tiene acceso a los campos públicos, y las clases deben marcarse con los atributos correctos (por ejemplo, XmlAttribute). Incluso en el marco básico, no todo es compatible con XmlSerializer. System.Collections.Generic.Dictionary <> por ejemplo.


El XmlSerializer tiene algunos inconvenientes.

  1. Debe conocer todos los tipos que se serializan. No puede pasarlo por una interfaz que representa un tipo que el serializador no conoce.
  2. No puede hacer referencias circulares.
  3. Se serializará el mismo objeto varias veces si se hace referencia a él varias veces en el gráfico de objetos.
  4. No se puede gestionar la serialización de campos privados.

Yo (estúpidamente) escribí mi propio serializador para resolver algunos de estos problemas. No hagas eso; es mucho trabajo y encontrarás errores sutiles meses después. Lo único que obtuve al escribir mi propio serializador y formateador fue una mayor apreciación de las minucias involucradas en la serialización de gráficos de objetos.

Encontré el NetDataContractSerializer cuando salió WCF. Hace todas las cosas desde arriba que XmlSerializer no hace. Impulsa la serialización de una manera similar a XmlSerializer. Uno decora varias propiedades o campos con atributos para informar al serializador qué serializar. Reemplacé el serializador personalizado que había escrito con NetDataContractSerializer y quedé muy satisfecho con los resultados. Lo recomendaría muchísimo.


La única limitación que puedo pensar es que XmlSerialization es opt-out; es decir, cualquier propiedad de una clase que no desee serializar DEBE estar decorada con [XmlIgnore]. Contraste eso con DataContractSerializer donde todas las propiedades son opt-in, debe declarar explícitamente los atributos de inclusión. Aquí hay un buen artículo .

Las imágenes o sus matrices binarias se serializan como texto codificado en base64 por XmlSerializer.


No estoy seguro si hay alguna limitación ... Pero había un error de pérdida de memoria en XmlSerialization en .NET 1.1, de alguna manera tenía que crear un objeto de serializador de memoria caché para evitar este problema ... De hecho, no estoy seguro de si este problema se ha corregido en .net 2.0 o posterior ...


Por ejemplo, no puede serializar clases implementando la interfaz IDictionary.


En general, creo que el XmlSerializer es una opción deficiente para cualquier POCO que sea más que solo un DTO. Si necesita XML específico, puede ir a la ruta Xml * Attribute y / o IXmlSerializable, pero le queda un objeto bastante destrozado.

Para algunos propósitos, sigue siendo una elección obvia, incluso con sus limitaciones. Pero, por el simple hecho de almacenar y volver a cargar datos, he descubierto que BinaryFormatter es una opción mucho más fácil con menos inconvenientes.

Aquí hay una lista de algunas molestias con XmlSerializer: la mayoría de las veces me han picado en algún momento u otras, y otras las encontré en MSDN :

  • Requiere un public, no args constructor
  • Solo serializa propiedades y campos públicos de lectura / escritura
  • Requiere que se conozcan todos los tipos
  • En realidad llama a get_ * y set_ *, por lo que se ejecutará la validación, etc. Esto puede ser bueno o malo (piense también en el orden de las llamadas)
  • Solo serializará las colecciones IEnumerable o ICollection conforme a reglas específicas

XmlSerializer brinda un tratamiento especial a las clases que implementan IEnumerable o ICollection. Una clase que implementa IEnumerable debe implementar un método Public Add que tome un solo parámetro. El parámetro del método Add debe ser del mismo tipo que se devuelve desde la propiedad Current en el valor devuelto por GetEnumerator, o una de las bases de ese tipo.

Una clase que implementa ICollection (como CollectionBase) además de IEnumerable debe tener una propiedad pública indexada de Elemento (indizador en C #) que toma un número entero, y debe tener una propiedad de Cuenta pública de tipo entero. El parámetro para el método Agregar debe ser del mismo tipo que se devuelve desde la propiedad Artículo o una de las bases de ese tipo. Para las clases que implementan ICollection, los valores que se serializarán se recuperarán de la propiedad del Item indexado, no llamando a GetEnumerator.

  • No serializa IDictionary
  • Utiliza ensamblajes generados dinámicamente, que pueden no descargarse del dominio de la aplicación.

Para aumentar el rendimiento, la infraestructura de serialización XML genera dinámicamente conjuntos para serializar y deserializar tipos especificados. La infraestructura encuentra y reutiliza esos conjuntos. Este comportamiento solo ocurre cuando se usan los siguientes constructores:

XmlSerializer.XmlSerializer (Type) XmlSerializer.XmlSerializer (Type, String)

Si usa cualquiera de los otros constructores, se generan múltiples versiones del mismo ensamblado y nunca se descargan, lo que da como resultado una pérdida de memoria y un rendimiento deficiente.

  • No se puede serializar ArrayList [] o List <T> []
  • Tiene otros casos de bordes extraños

El XmlSerializer no se puede crear una instancia para serializar una enumeración si las siguientes condiciones son verdaderas: La enumeración es de tipo unsigned long (ulong en C #) y la enumeración contiene cualquier miembro con un valor mayor a 9,223,372,036,854,775,807.

La clase XmlSerializer ya no serializa los objetos que están marcados como [Obsoleto].

Debe tener permiso para escribir en el directorio temporal (como lo define la variable de entorno TEMP) para deserializar un objeto.

  • Requiere leer .InnerException para obtener información útil sobre errores

Para las colecciones, necesitan tener un método Agregar tomando un solo argumento. Si solo necesita un formato de texto y no específicamente xml, puede intentar con JSON. He desarrollado uno para .NET, JsonExSerializer , y hay otros disponibles también en http://www.json.org .


Otro problema es que llamar al constructor de XmlSerializer compilará código en tiempo de ejecución y generará una DLL temporal (en la carpeta% temp%) con el código para realizar la de / serialización.

Puede ver el código si agrega las siguientes líneas a app.config:

<system.diagnostics> <switches> <add name="XmlSerialization.Compilation" value="4"/> </switches> </system.diagnostics>

Esto toma mucho tiempo la primera vez que serializa una clase y necesita un código con permisos para compilar y escribir en el disco.

Una forma de evitar esto es precompilar estas DLL usando la herramienta sGen.exe que viene con VS 2005+.

Mire aquí para más información .