Como usar o DataContractJsonSerializer

Observação

Este artigo é sobre DataContractJsonSerializer. Para a maioria dos cenários que envolvem serialização e desserialização do JSON, recomendamos as APIs no namespace System.Text.Json.

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.

Este artigo demonstra como serializar objetos do tipo .NET em dados codificados por JSON e, em seguida, desserializar os dados no formato JSON em instâncias de tipos .NET. Este exemplo usa um contrato de dados para demonstrar a serialização e a desserialização de um tipo Person definido pelo usuário e usa o DataContractJsonSerializer.

Normalmente, a serialização e desserialização do JSON são tratados 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. No entanto, em alguns casos, pode ser necessário trabalhar diretamente com dados JSON.

Este artigo é baseado na amostra DataContractJsonSerializer.

Para definir o contrato de dados para um tipo de Pessoa

  1. Defina o contrato de dados para Person anexando DataContractAttribute à classe e o atributo DataMemberAttribute aos membros que você deseja serializar. Para obter mais informações sobre contratos de dados, consulte Criando contratos de serviço.

    [DataContract]
    internal class Person
    {
        [DataMember]
        internal string name;
    
        [DataMember]
        internal int age;
    }
    

Para serializar uma instância do tipo Person para JSON

Observação

Se ocorrer um erro durante a serialização de uma resposta de saída no servidor ou, por qualquer outro motivo, ela poderá não ser retornada ao cliente como uma falha.

  1. Crie uma instância do tipo Person.

    var p = new Person();
    p.name = "John";
    p.age = 42;
    
  2. Serialize o objeto Person em um fluxo de memória usando o DataContractJsonSerializer.

    var stream1 = new MemoryStream();
    var ser = new DataContractJsonSerializer(typeof(Person));
    
  3. Use o método WriteObject para gravar dados JSON no fluxo.

    ser.WriteObject(stream1, p);
    
  4. Mostre a saída JSON.

    stream1.Position = 0;
    var sr = new StreamReader(stream1);
    Console.Write("JSON form of Person object: ");
    Console.WriteLine(sr.ReadToEnd());
    

Para desserializar uma instância do tipo Person de JSON

  1. Desserialize os dados codificados por JSON em uma nova instância de Person usando o método ReadObject da classe DataContractJsonSerializer.

    stream1.Position = 0;
    var p2 = (Person)ser.ReadObject(stream1);
    
  2. Mostre os resultados.

    Console.WriteLine($"Deserialized back, got name={p2.name}, age={p2.age}");
    

Exemplo

// Create a User object and serialize it to a JSON stream.
public static string WriteFromObject()
{
    // Create User object.
    var user = new User("Bob", 42);

    // Create a stream to serialize the object to.
    var ms = new MemoryStream();

    // Serializer the User object to the stream.
    var ser = new DataContractJsonSerializer(typeof(User));
    ser.WriteObject(ms, user);
    byte[] json = ms.ToArray();
    ms.Close();
    return Encoding.UTF8.GetString(json, 0, json.Length);
}

// Deserialize a JSON stream to a User object.
public static User ReadToObject(string json)
{
    var deserializedUser = new User();
    var ms = new MemoryStream(Encoding.UTF8.GetBytes(json));
    var ser = new DataContractJsonSerializer(deserializedUser.GetType());
    deserializedUser = ser.ReadObject(ms) as User;
    ms.Close();
    return deserializedUser;
}

Observação

O serializador JSON gera uma exceção de serialização para contratos de dados que têm vários membros com o mesmo nome, como mostrado no código de exemplo a seguir.

[DataContract]
public class TestDuplicateDataBase
{
    [DataMember]
    public int field1 = 123;
}

[DataContract]
public class TestDuplicateDataDerived : TestDuplicateDataBase
{
    [DataMember]
    public new int field1 = 999;
}

Confira também