Serializando objetos com SOAP.

Bom, primeiramente, sejam bem-vindos. Este é o primeiro post deste blog, que tem o intuito de discutir e avançar no aprendizado do Microsoft .Net Framework.
Hoje vou falar de Serialização de dados, um assunto um tanto extenso que daria muitos outros posts, se eu fosse falar sobre todos os meios de serializar objetos.

Mas o que é serialização e quando vou precisar usar?

Quando você precisa converter seus objetos em documentos para serem usados por outros processos ou transmitidos pela rede, você os está serializando.
Você precisará deste processo quando outras aplicações necessitarem obter informações dos seus objetos.

Existem dois formatos de serialização no namespace System.Runtime.Serialization :

* BinaryFormatter: Encontrado no namespace System.Runtime.Serialization.Formatters.Binary . É o meio mais eficiente de serialização, utilizado quando os objetos serão lidos por aplicações desenvolvidas no .Net Framework.
* SOAP Formatter: Encontrado no namespace System.Runtime.Serialization.Formatters.Soap . Formato baseado no XML, mais útil para aplicações não desenvolvidas no .Net e para transferir dados por redes, pois é o formato que tem mais sucesso contra bloqueios de firewalls que o BinaryFormatter.Hoje vou falar sobre o SOAPFormatter. Em breve, mostro o funcionamento do BinaryFormatter.

Para usar o SOAPFormatter, adicione uma referência ao System.Runtime.Serialization.Formatters.Soap.dll no seu projeto. Os passos básicos para serializar neste formato são os seguintes:

* Crie um stream para salvar a saída no disco;
* Crie um objeto SOAPFormatter;
* Use o SOAPFormatter.Serialize() para serializar os dados no arquivo.

Primeiro, vamos criar nossa classe que será serializada. Para tornar uma classe serializável, aplique o atributo [Serializable] à ela.

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

namespace Serializa_Funcionario
{
[Serializable]
class Funcionario
{
public string nome;
public DateTime dataNascimento;
public int idade;

public Funcionario(string _nome, DateTime _dataNascimento, int _idade)
{
nome = _nome;
dataNascimento = _dataNascimento;
idade = _idade;
}

public Funcionario() {}

public override string ToString()
{
return nome + ” nasceu em ” + dataNascimento.ToShortDateString() + ” e tem ” + idade.ToString() + ” anos de idade”;
}

}
}

A única diferença desta classe para qualquer outra é que ela tem o atributo Serializable. Aliás, na dúvida de saber se suas classes serão serializadas ou não no futuro, aplique este atributo.
Agora vamos criar a classe Program, a qual irá executar o console:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Soap;

namespace Serializa_Funcionario
{
class Program
{
static void Main(string[] args)
{
if (args.Length == 0)
{
// Se nao houver nenhum parâmetro, desserializa o arquivo existente.
Funcionario func = Deserialize();
Console.WriteLine(func.ToString());
}
else
{
try
{
if (args.Length != 3)
{
throw new ArgumentException(“Precisa entrar com três parâmetros.”);
}

DateTime data = new DateTime(Int32.Parse(args[1]), Int32.Parse(args[2]), Int32.Parse(args[3]));
int idade = DateTime.Now.Year – dataNascimento.Year;
Funcionario func = new Funcionario(args[0], data, idade);
Console.WriteLine(func.ToString());

Serialize(func);
}
catch (Exception ex)
{
DisplayUsageInformation(ex.Message);
}
}
}

private static void DisplayUsageInformation(string message)
{
Console.WriteLine(“\nERROR:Parâmetros inválidos. ” + message);
Console.WriteLine(“\nSerializa_Fucionario \”Nome\” Year Month Date”);
Console.WriteLine(“\nPor Exemplo:\nSerialize_Fucionario \”Luiz\” 1922 11 22″);
Console.WriteLine(“\nOu, execute o command sem parâmetros para exibir o funcionário anterior.”);
}

private static void Serialize(Funcionario func)
{
// Crio o arquivo para salvar as informações
FileStream fs = new FileStream(@”C:/Funcionario.xml”, FileMode.Create);

// Crio um SoapFormatter
SoapFormatter sp = new SoapFormatter();

// Uso o SoapFormatter para serializar o objeto no arquivo
sp.Serialize(fs, func);

// Fecho o arquivo
fs.Close();

}

private static Funcionario Deserialize()
{
Funcionario dsFunc = new Funcionario();

//Abro o arquivo para ler os dados
FileStream fs = new FileStream(@”C:/Funcionario.xml”, FileMode.Open);

// Crio um SoapFormatter
SoapFormatter sp = new SoapFormatter();

// Uso o SoapFormatter para desserializar o objeto
dsFunc = (Funcionario)sp.Deserialize(fs);

// Fecho o arquivo
fs.Close();

return dsFunc;
}
}
}

Aqui, você precisa preencher as propriedades que serão serializadas. Quando abrir o prompt de comando, digite os parâmetros necessários: nome, data e idade. Se nenhum parâmetro for inserido, vai ser desserializado o arquivo, se existir.

O método Serialize recebe o objeto Funcionario para serializar as propriedades:

private static void Serialize(Funcionario func)
{
// Crio o arquivo onde serão salvas as informações:
FileStream fs = new FileStream(@”C:/Funcionario.xml”, FileMode.Create);

// Crio um objeto SOAPFormatter
SoapFormatter sp = new SoapFormatter();

// Uso o SOAPFormatter para serializar as informações no arquivo, passando o stream e a classe.
sp.Serialize(fs, func);

// Fecho o arquivo
fs.Close();

}

O processo inverso é a desserialização. É quando a aplicação remota vai ler as propriedades do seu objeto no arquivo.
Observe que você deve sempre usar o mesmo formato que serializou para desserializar:

private static Funcionario Deserialize()
{
Funcionario dsFunc = new Funcionario();

// Abre o arquivo
FileStream fs = new FileStream(@”C:/Funcionario.xml”, FileMode.Open);

// Cria o SoapFormatter para desserializar
SoapFormatter sp = new SoapFormatter();

// Usa o SoapFormatter para desserializar o arquivo para o objeto.
dsFunc = (Funcionario)sp.Deserialize(fs);

// Fecha o arquivo
fs.Close();

return dsFunc;
}

Alguns detalhes sobre Serialização:

* O SOAPFormatter não dá suporte para compatibilidade entre versões. Se você tem uma aplicação na versão 1.0, não conseguirá desserializar na versão 2.0.
* O formato BinaryFormatter tem total suporte a versões diferentes.
* Use SOAPFormatter se você precisar de portabilidade e BinaryFormatter para ter mais eficiência.

Em breve irei postar mais sobre serialização, é um assunto que gosto e muito amplo. Deixo uma questão para você:

Se o SOAPFormatter não dá suporte para compatibilidade entre versões, o que fazer quando precisar mudar a versão da aplicação? Vamos escrever toda a serialização de novo?

Um abraço, até a próxima.


About this entry