For a quick translation click here.
A serialização de objectos é por definição uma técnica usada para persistir objectos, pode ser utilizada para gravar objectos em disco, fazer a transmissão remota de objectos, ou gravar os objectos em base de dados.
Podemos apontar mais utilizações como por exemplo:
- Guardar as preferências de um utilizador num objecto
- Passar objectos entre aplicações
- Modificar ou transformar o conteúdo de um objecto
É uma funcionalidade muito poderosa, e o destino a dar á sua utilização depende em ultima análise da imaginação e das necessidades de cada um, as possibilidades são variadas.
Em .Net existem dois formatos em que um objecto pode ser serializado, o formato binário ou o formato xml. Vamos ver como podemos usar a serialização neste ultimo caso, uma vez que um ficheiro xml permite uma fácil leitura e manipulação do seu conteúdo, sendo neste momento possivelmente o formato mais usado para a troca de dados.
Para um objecto ser serializado em Xml tem de cumprir os seguintes requisitos:
- Tem de ter um default constructor, ou seja um construtor sem parâmetros
- Todas as propriedades a serem serializadas tem de ser Read\Write, as propriedades Real Only não são serializáveis
E tem também algumas regras:
- Apenas as propriedades e membros públicos são serializáveis
- A serialização não inclui informação sobre o tipo, ou seja para Serializar e Deserializar é necessário indicar qual o tipo do objecto
As classes e atributos necessário para a serialização estão no namespace System.Xml.Serialization, vamos para este exemplo explorar a classe XmlSerializer e alguns atributos úteis para a serialização.
Esta é a classe principal deste namespace, e tal como está descrito na documentação permite converter as propriedades e membros públicos para um formato que lhes permita serem guardados ou transportados. E também recriar um objecto a partir desse formato, no nosso caso esse formato é Xml.
Os principais métodos desta classe são:
Serialize: Permite guardar o objecto para um stream
Deserialize: Permite recriar o objecto a partir de um stream
Este stream pode ser manipulado de várias formas, pode ser gravado para um ficheiro xml, e deste modo vamos usar a serialização para persistir o objecto, ou então o seu valor pode ser escrito numa string, neste caso pode ou não persistir, dependendo da utilização que for dada a essa string, pode ainda servir por exemplo para transferir um objecto utilizando para tal um stream http.
Atributos:
Além da classe XmlSerializer, existem várias classes de atributos, atributos esses que podem ser usados para definir com um objecto vai ser serializado, estão descritos na documentação pelo que vamos ver apenas alguns exemplos para ilustrar a sua utilização
[XmlRoot("Order", Namespace = "http://www.sampleOne.com/sales")]
O atributo XmlRoot é usado ao nível da classe e permite definir por exemplo qual o nome do root element do Xml, e qual o seu namespace
[XmlAttribute("customerId")]
Por defeito os elementos da classe a serializar são escritos no xml na forma de nós o que o atributo XmlAttribute permite é indicar que determinado elemento vai ser guardado como atributo de um nó
[XmlIgnore]
Tal como indica o nome este atributo permite identificar que determinada propriedade ou membro não irá ser serializado.
Vamos ver agora um pequeno exemplo, para este exemplo vamos usar as seguintes classes:
As classes SalesOrder e SalesOrderItem, representam tal como os nomes indicam uma encomenda e os respectivos items.
Em ambas as classes todos os membros são privados, estando encapsulados por propriedades publicas, sendo assim apenas estas propriedades serão serializadas.
Para fazer a serialização e deserialização vamos usar a seguinte classe:

O método Serialize retorna uma string xml com o conteúdo de um dado objecto, o método Deserialize faz o inverso, ou seja, a partir de uma string xml com o conteúdo de um objecto e do seu tipo, cria uma nova instancia desse objecto. Além disso permite a escolha de qual o encoding a utilizar nestes métodos.
Estão aqui em detalhe cada um dos métodos, espero que os comentários sejam suficientemente elucidativos:
public static class MemorySerializer
{
#region Private Static Members
// The default encoding to use in the serialization process
private static Encoding encoding = Encoding.UTF8;
#endregion
#region Public Methods
/// <summary>
/// Serializes the specified source.
/// </summary>
/// <param name="source">The source.</param>
/// <returns></returns>
public static string Serialize(object source)
{
// The string to hold the object content
String content;
// Create a memoryStream into which the data can be written and readed
using (MemoryStream stream = new MemoryStream())
{
// Create the xml serializer, the serializer needs to know the type
// of the object that will be serialized
XmlSerializer xmlSerializer = new XmlSerializer(source.GetType());
// Create a XmlTextWriter to write the xml object source, we are going
// to define the encoding in the constructor
using (XmlTextWriter writer = new XmlTextWriter(stream, Encoding))
{
// Save the state of the object into the stream
xmlSerializer.Serialize(writer, source);
// Flush the stream
writer.Flush();
// Read the stream into a string
using (StreamReader reader = new StreamReader(stream, Encoding))
{
// Set the stream position to the begin
stream.Position = 0;
// Read the stream into a string
content = reader.ReadToEnd();
}
}
}
// Return the xml string with the object content
return content;
}
/// <summary>
/// Deserializes the specified object string.
/// </summary>
/// <param name="content">The object string.</param>
/// <param name="type">Type of the object.</param>
/// <returns></returns>
public static object Deserialize(string content, Type type)
{
// The object to be returned
object source;
// Create a memorystream into which the object string will be written
using (MemoryStream stream = new MemoryStream())
{
// Create the sream writer with the specified encoding
using (StreamWriter writer = new StreamWriter(stream, Encoding))
{
// Write the object content into the stream
writer.Write(content);
// Flush the stream
writer.Flush();
// Create the serializer, we must provide the object type to the constructor
XmlSerializer xmlSerializer = new XmlSerializer(type);
// Set the stream position to the begin
stream.Position = 0;
// Deserialize the object
source = xmlSerializer.Deserialize(stream);
}
}
// Return the new object
return source;
}
#endregion
#region Public Properties
/// <summary>
/// Gets or sets the encoding.
/// </summary>
/// <value>The encoding.</value>
public static Encoding Encoding
{
get { return encoding; }
set { encoding = value; }
}
#endregion
}
O exemplo de utilização consiste no seguinte:
Uma pequena Windows Application, que permite a edição do conteúdo dos objecto num layout gráfico e também a sua edição em Xml, deste modo podemos editar directamente o xml e verificar como o objecto criado reflecte essas mesmas alterações.
Este é um pequeno exemplo de uma das múltiplas utilizações da serialização, e de como pode ser usada para visualizar e editar o conteúdo de um objecto.
Links:
Sample Application


