.NET

7 set, 2017

C# –  Serializar/Deserializar JSON usando contrato de dados (DataContract)

Publicidade

Neste artigo vou mostrar como podemos serializar e deserializar arquivos JSON usando um contrato de dados na linguagem C#.

Vou começar definindo o que é JSON (para quem esta chegando agora)…

JSON (JavaScript Object Notation) é um formato eficiente de codificação de dados que permite a troca rápida de pequenas quantidades de dados entre navegadores cliente e serviços Web habilitados para AJAX.

Se você necessita de suporte a JSON, mas não estiver criando um serviço AJAX, a classe DataContractJsonSerializer possibilita serializar diretamente objetos .NET em dados JSON e desserializar esses dados em instâncias de tipos .NET como veremos neste artigo.

Normalmente o processo de serialização e desserialização JSON é tratado automaticamente pelo Windows Communication Foundation (WCF) quando você usa tipos de contrato de dados em operações de serviço que são expostas em pontos de extremidade habilitados para AJAX. Entretanto, em alguns casos, convém trabalhar com dados JSON diretamente.

Um contrato de dados é um contrato formal entre um serviço e um cliente que abstratamente descreve os dados a serem trocados. Ou seja, para se comunicar, o cliente e o serviço não precisam compartilhar os mesmos tipos, apenas os mesmos contratos de dados.  Assim, um contrato de dados define precisamente, para cada parâmetro ou tipo retorno, quais dados são serializáveis (transformadas em XML) a serem trocados.

Podemos criar explicitamente um contrato de dados usando os atributos DataContractAttribute e DataMemberAttribute, e, isso é feito por meio da aplicação do atributo DataContractAttribute ao tipo. Esse atributo pode ser aplicado a classes, estruturas e enumerações.

O atributo DataMemberAttribute deve ser aplicado, em seguida, para cada membro do tipo de contrato de dados para indicar que ele é um membro de dados, ou seja, que ele deverá ser serializado.

A serialização pode ser feita pela classe DataContractSerializer que serializa objetos para JSON e deserializa JSON para objetos; essa classes infere o contrato de dados e serializa todos os tipos visíveis publicamente. Dessa forma, todas as propriedades de leitura/gravação públicas e campos do tipo são serializados.

A seguir vemos um exemplo de utilização dos atributos DataContractAttribute e DataMemberAttribute em uma classe Pessoa.cs:

[DataContract]
 public class Pessoa
 {
 public Pessoa(string nome, string sobrenome, DateTime nascimento)
 {
 Nome = nome;
 Sobrenome = sobrenome;
 Nascimento = nascimento;
 }
 [DataMember]
 public string Nome {get; set;}
 [DataMember]
 public string Sobrenome { get; set; }
 [DataMember]
 public DateTime Nascimento { get; set; }
}

Vamos usar essa classe em nosso exemplo prático que mostra como podemos serializar e deserializar JSON usando um contrato de dados.

A partir da versaõ 3.5 da plataforma .NET, você não precisa adicionar os atributos [DataContract] e [DataMember] nas classes para realizar a serialização – se você não fizer isso, o serializador do contrato de dados irá serializar todas as propriedades públicas em sua classe, assim como o serializador XML.

No entanto, por não adicionar esses atributos, você perde um monte de recursos úteis, como:

  • Sem [DataContract], você não pode definir um namespace XML para seus dados;
  • Sem [DataMember], não é possível serializar propriedades ou campos não-públicos;
  • Sem [DataMember], você não pode definir uma ordem de serialização (Order=) e o DCS (DataContractSerializer) irá serializar todas as propriedades em ordem alfabética;
  • Sem [DataMember], você não pode definir um nome diferente para sua propriedade (Name=);- Sem [DataMember], você não pode definir coisas como IsRequired= ou outros atributos úteis;
  • Sem [DataMember], você não pode deixar de fora determinadas propriedades públicas – todas as propriedades públicas serão serializadas pelo DCS;

 

Vejamos a seguir um exemplo bem simples de serialização/deserialização JSON usando um contrato de dados.

 

Criando o projeto no VS 2015 Community

Abra o VS 2015 Community e clique em New Project;

A seguir selecione Visual C# -> Windows Forms Application;

Informe o nome JsonDemo e clique no botão OK;

No formulário form1.cs vamos incluir os seguintes controles a partir da ToolBox:

  • 1 TextBox – Multiline=True, Name= txtJsonFonte
  • 1 PropertyGrid – name = propertyGrid1 , Anchor = Top, Bottom, Right, PropertySort = Alphabetical
  • 2 Buttons – btnSerializar e btnDeserializar

 

Nota:  O controle PropertyGrid fornece uma interface para exibir propriedades de um objeto.

Disponha os controles no formulário conforme o leiaute da figura abaixo:

DataContract

Devemos incluir no projeto uma referência ao namespace:  System.Runtime.Serialization e criar a classe Pessoa com o código exibido no início do artigo.

Criando a classe JsonHelper para serializar e deserializar

Vamos criar uma classe chamada JsonHelper em nosso projeto e definir nesta classe dois métodos:

  • Serializar(T)(T obj) – serializa objetos para JSON;
  • Deserializar<T>(string json) – deserializar JSON para objetos.

 

A implementação do código desta classe é dado a seguir:

using System.Text;
using System.Runtime.Serialization.Json;
using System.IO;
namespace Macoratti
{
 public class JsonHelper
 {
 public static string Serializar<T>(T obj)
 {
 DataContractJsonSerializer serializer = new DataContractJsonSerializer (typeof (T));
 MemoryStream ms = new MemoryStream ();
 serializer.WriteObject (ms, obj);
 return Encoding.UTF8.GetString (ms.ToArray ());
 }
 public static T DeSerializar<T>(string json)
 {
 DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (T));
 MemoryStream ms = new MemoryStream (Encoding.UTF8.GetBytes (json));
 return (T)ser.ReadObject (ms);
 }
 }
}

No código usamos a classe  DataContractJsonSerializer para realizar as tarefas de serialização e deserialização.

Implementando o código da interface

Vamos agora implementar o código onde vamos serializar a classe Pessoa para JSON e a seguir deserializar o JSON para objetos.

No formulário Form1.cs defina os seguintes namespaces:

  • using System;
  • using System.Windows.Forms;

 

A seguir no evento Click do botão – Serializar – inclua o código a seguir:

private void btnSerializar_Click(object sender, EventArgs e)
 {
Pessoa pessoa = new Pessoa("Jose Carlos", "Macoratti", new DateTime(1975, 3, 5));
 try
 {
txtJsonFonte.Text = Macoratti.JsonHelper.Serializar<Pessoa>(pessoa); txtJsonFonte.Text = Macoratti.JsonHelper.Serializar<Pessoa>(pessoa);      }
catch (System.Exception ex)
 {
MessageBox.Show (ex.ToString ());
 }
 }

Neste código criamos um objeto pessoa com algumas informações e usamos o método Serializar() da classe JsonHelper para serializar o objeto para JSON exibindo no TextBox.

A seguir no evento Click do botão – DeSerializar – inclua o código a seguir:

private void btnDeserializar_Click(object sender, EventArgs e)
 {
 if (txtJsonFonte.Text == "")
 {
 MessageBox.Show ("Voce precisa criar o arquivo JSON primeiro ",
 "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
 return;
 }
 try
 {
 Pessoa pessoa = Macoratti.JsonHelper.DeSerializar<Pessoa>(txtJsonFonte.Text);
 propertyGrid1.SelectedObject = pessoa;
 }
 catch (Exception ex)
 {
 MessageBox.Show(ex.ToString());
 }
 }

O código acima usa o método DeSerializar<>() da classe JsonHelper para obter o JSON e gerar o objeto exibindo-o no propertyGrid.

Executando o projeto iremos obter o seguinte resultado:

DataContract

Você pode incrementar o código do projeto tornando-o mais genérico de forma a informar a classe que deseja serializar/deserializar.

Pegue o projeto completo aqui:   JsonDemo.zip