Personalizar la serialización de tipos en XML

Serialización con XML

Serialización con XML

Cuando queremos guardar en fichero XML alguna estructura de datos podemos recurrir a la serialización.

Con las funciones actuales disponibles para el manejo de XML en C# la serialización de estructuras de datos es relativamente sencilla. Pero el problema nos surge cuando en la estructura de datos hay algún tipo de objeto que, o no nos interesa el modo en que hace la conversión, por la razón que sea, o por que la serialización de ese objeto no esta soportada.

Para solucionar este problema C# nos proporciona los atributos [XMLIgnore], para indicarle al proceso de serialización que ignore ese objeto, y [XmlElement], donde le indicamos como se va ha convertir ese objeto.

Para indicar al proceso de serialización del XML que ese objeto lo ignore, solo tendremos que anteponer el atributo [XMLIgnore] delante del objeto que queremos. Por ejemplo:

[XmlIgnore]
public Image Imagen { get; set; }

En este caso el tipo “Image” no soporta serialización, por lo que la conversión la tendremos que realizar nosotros mismos.

Una que le hemos dicho que ignore ese objeto le tenemos que indicar como vamos a convertirlo. Para ello tendremos que crear nuestra función de conversión he indicarle que la use en para ese elemento. Para indicarle que objeto vamos a utilizar solo tenemos que utilizar el atributo [XmlElement(“Nombre_del_objeto”], le indicamos el nombre que le hemos dado al objeto, no el tipo. Por ejemplo:

[XmlElement("Imagen")]
public byte[] ConvertImageToByte
{
    // Devolvemos una cadena de byte cuando nos pasan la imagen
    get
        {
            byte[] ImagenByte = null;
            // Si el valor pasado es distinto a null, pasamos la conversión, sino pasamos null
            if (Imagen != null)
            {
                // Convertimos la imagen en un array de byte[]
                ImageConverter ConvertirImagen = new ImageConverter();
                ImagenByte = (byte[])ConvertirImagen.ConvertTo(Imagen, typeof(byte[]));
            }
        return ImagenByte;
    }

    // Devolvemos una imagen cuando nos pasan una cadena de byte[]
    set
    {
        // Si el valor pasado es null
        if (value == null)
        {
            // Devolvemos otro null
            Imagen = null;
        }
        else
        {
            // Convertimos el array de bytes[] en una imagen
            ImageConverter ConvertirImagen = new ImageConverter();
            Imagen = (Image)ConvertirImagen.ConvertFrom(value);
        }
    }
}

En el ejemplo se utiliza el objeto “Imagen” del ejemplo anterior que es de tipo “Image”, que no esta soportado por la serialización de XML. Lo que hacemos es convertilo en un array de byte para poderlo guardar en el fichero.

La parte del “get” la serialización de XML la utilizara cuando va ha grabar los datos, leeremos desde el objeto “Imagen” la imagen que queremos y con ayuda de la función “ImageConverter” la convertimos en un array de byte, le indicamos el formato que vamos a utilizar en el segundo parámetro que le pasamos a la función en este caso “typeof(byte[]).

ImageConverter ConvertirImagen = new ImageConverter();

ImagenByte = (byte[])ConvertirImagen.ConvertTo(Imagen, typeof(byte[]));

La parte del “set” la serialización de XML la usa cuando lee los datos desde el fichero de XML. Le pasara la cadena de byte que tiene grabada y cargara en la variable “Imagen” la imagen es su formato correcto, tipo “Image”. Para la conversión volvemos a utilizar la función “ImageConverter”, en este caso nos devolverá un objeto, para pasárselo a la variable solo tenemos que indicar que ese objeto es de tipo “Image”

ImageConverter ConvertirImagen = new ImageConverter();
Imagen = (Image)ConvertirImagen.ConvertFrom(value);

Si lo aplicamos a un objeto que es de un tipo soportado por la serialización de XML, lo que hará, sera ignorar su método de serialización y utilizar el que le indiquemos.

Si tienes alguna sugerencia sera bienvenida, deja un comentario.