Code Screen

Serialização em C#

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. 

Leave a Reply

Your email address will not be published. Required fields are marked *