Antes de irmos diretamente para o código, vamos entender brevemente o que é serialização e deserialização.
Serializar é o processo de transformar um objeto que você possui em um stream de bytes ou de texto. Deserializar por sua vez, é exatamente o oposto, é você converter um stream de bytes ou de texto em um objeto novamente.
Para nos ajudar nesse processo, o .NET Framework nos oferece algumas classes que podem ser encontradas nos namespaces System.Runtime.Serialization e System.Xml.Serialization, além de nos oferecer por padrão três mecanismos serialização/deserialização:
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public int Age;
public Person() { }
public Person(int id, string firstName, string lastName, string email, int age)
{
Id = id;
FirstName = firstName;
LastName = lastName;
Email = email;
Age = age;
}
}
- BinaryFormatter
- XmlSerializer
- DataContractSerializer
Logo mais nesse artigo veremos como utilizar cada um desses mecanismos na prática, portanto usaremos a classe Person, que se encontra logo abaixo como base para nossos exemplos.
Binary Serialization
A serailização Binária, como o próprio nome já sugere, serializa um objeto ou dado para o formato binário. Esse tipo de serialização armazena não somente os dados, mas também o tipo de objeto que esta sendo serializado.
Para utilizarmos esse tipo de serialização, devemos marcar nossa classe como o atributo [Serializable], sendo que todos os campos podem ser serializados, inclusive os marcados como private, portanto caso queiramos impedir que algum campo da nossa classe não seja serializado, devemos marca-la com o atributo [NonSerialized], também é importante ressaltarmos que propriedades serão sempre serializadas e que nenhum construtor é executado nesse tipo de serialização.
Outra característica importante é que esse tipo de serialização também é “mais rigorosa” que as demais, se o serializador binário não achar algum campo por exemplo, ele retornará uma Exception. No caso de uma atualização de versão por exemplo, você pode adicionar o [OptionalFieldAttribute] no novo campo adicionado para que a serialização binária entenda que esse campo não existia antes, por exemplo.
//Criamos uma nova pessoa para serializarmos
var person = new Person(1, "João", "da Silva", "joao.silva@xpto.com", 50);
//Instanciamos a classe BinarryFormatter
var binaryFormatter = new BinaryFormatter();
//Criamos um arquivo .bin que receberá os dados serializados do objeto person
using (var fileStream = new FileStream("ericsonf.bin", FileMode.Create))
{
binaryFormatter.Serialize(fileStream, person);
}
Console.WriteLine("Serialização Concluida");
//Abrimos o arquivo serializado anteriormente para podermos deserializa-lo.
using (var fileStream = new FileStream("ericsonf.bin", FileMode.Open))
{
var p = (Person)binaryFormatter.Deserialize(fileStream);
}
Console.WriteLine("Deserialização Concluida");
XML Serialization
Ao contrário do modelo de serialização anterior, o XML é um tipo de dado legivel também para seres humanos, e é fracamente acoplado, ou seja, se você adicionar propriedades ou campos ao seu objeto a ser serializado ele não notará.
Assim como na serialização binária, para serializamos, precisamos marcar o objeto como o atributo [Serializable],
entretanto, aqui somente os campos e/ou propriedades publicas são
serializadas. Caso queiramos que um campo e/ou propriedade não seja
serializado, devemos marca-lo com o atributo [XmlIgnore]. Vale lembrar que propriedades também podem ser ignoradas e não somente campos, além de que, na serialização XML se faz necessário ter um construtor vazio na classe diferentemente do modelo de serialização anterior.
//Criamos uma nova pessoa para serializarmos
var person = new Person(1, "João", "da Silva", "joao.silva@xpto.com", 50);
//Instanciamos a classe XmlSerializer, e "dizemos" a ele que tipo de objeto vamos serializar.
var xml = new XmlSerializer(typeof(Person));
//Criamos um arquivo .xml que receberá os dados serializados do objeto person
using (var fileStream = new FileStream("ericsonf.xml", FileMode.Create))
{
xml.Serialize(fileStream, person);
}
Console.WriteLine("Serialização Concluida");
//Abrimos o arquivo serializado anteriormente para podermos deserializa-lo.
using (var fileStream = new FileStream("ericsonf.xml", FileMode.Open))
{
var p = (Person)xml.Deserialize(fileStream);
}
Console.WriteLine("Deserialização Concluida");
Data Contract
O Data Contract Serializer é utilizado pelo WCF para serializar seus objetos tanto em XML quanto em JSON. Esse tipo de serialização é feita pelas classes DataContractSerializer para XML e DataContractJsonSerializer para JSON (discutido mais adiante).
Nesse modelo eu preciso marcar meu objeto a ser serializado com o atributo [DataContract],
além de que nesse modelo ao contrario dos outros, eu preciso marcar
todos os membros que eu desejo serializar explicitamente com o atributo [DataMember], caso eu deseje ignorar algum membro, devemos marca-lo com o atributo [IgnoreDataMember] ou se preferir, apenas deixa-lo sem a marcação do atributo [DataMember]. Outra caracteristica importante é que nesse modelo, campos privados também pode ser serializados.
//Criamos uma nova pessoa para serializarmos
var person = new Person(1, "João", "da Silva", "joao.silva@xpto.com", 50);
//Instanciamos a classe DataContractSerializer, para serializarmos em XML e "dizemos" a ele que tipo de objeto vamos serializar.
var dataContract = new DataContractSerializer(typeof(Person));
//Criamos um arquivo .xml que receberá os dados serializados do objeto person
using (var fileStream = new FileStream("ericsonf.xml", FileMode.Create))
{
dataContract.WriteObject(fileStream, person);
}
Console.WriteLine("Serialização Concluida");
//Abrimos o arquivo serializado anteriormente para podermos deserializa-lo.
using (var fileStream = new FileStream("ericsonf.xml", FileMode.Open))
{
var p = (Person)dataContract.ReadObject(fileStream);
}
Console.WriteLine("Deserialização Concluida");
JSON Serialization
Utiliza-se também o Data Contract Serializer e suas respectivas caracteristicas para que a serilização seja efetuada, porém com uma única alteração, que ao invés de eu utilizar a classe DataContractSerializer eu utilizo a classe DataContractJsonSerializer para que possamos serializar em JSON.
//Criamos uma nova pessoa para serializarmos
var person = new Person(1, "João", "da Silva", "joao.silva@xpto.com", 50);
//Instanciamos a classe DataContractJsonSerializer, para serializarmos em JSON e "dizemos" a ele que tipo de objeto vamos serializar.
var dataContract = new DataContractJsonSerializer(typeof(Person));
//Criamos um arquivo .xml que receberá os dados serializados do objeto person
using (var fileStream = new FileStream("ericsonf.json", FileMode.Create))
{
dataContract.WriteObject(fileStream, person);
}
Console.WriteLine("Serialização Concluida");
//Abrimos o arquivo serializado anteriormente para podermos deserializa-lo.
using (var fileStream = new FileStream("ericsonf.json", FileMode.Open))
{
var p = (Person)dataContract.ReadObject(fileStream);
}
Console.WriteLine("Deserialização Concluida");
Bom
pessoal, a ideia desse artigo era mostrar a vocês as particularidades e
exemplos de como utilizar cada dos modelos de serialização utilizando
C#.
Espero que tenham gostado do artigo e até a próximo.