Compartilhar via


Weakly-typed JSON Serialization Sample

Ao serializar um tipo definido pelo usuário para um determinado formato de conexão ou desserializar um formato de conexão de volta para um tipo definido pelo usuário, o tipo definido pelo usuário fornecido deve estar disponível no serviço e no cliente. Normalmente, para fazer isso, o atributo DataContractAttribute é aplicado a esses tipos definidos pelo usuário e o atributo DataMemberAttribute é aplicado a seus membros. Esse mecanismo também se aplica ao trabalhar com objetos JavaScript Object Notation (JSON), conforme descrito no tópico Como: serializar e desserializar dados JSON.

Em alguns cenários, um serviço ou cliente do Windows Communication Foundation (WCF) deve acessar objetos JSON gerados por um serviço ou cliente que está fora do controle do desenvolvedor. À medida que mais serviços da Web expõem APIs JSON publicamente, pode se tornar impraticável para o desenvolvedor WCF construir tipos locais definidos pelo usuário para desserializar objetos JSON arbitrários.

O exemplo WeaklyTypedJson fornece um mecanismo que permite aos desenvolvedores do WCF trabalhar com objetos JSON desserializados e arbitrários, sem criar tipos definidos pelo usuário. Isso é conhecido como serialização de tipagem fraca de objetos JSON, porque o tipo no qual um objeto JSON desserializa não é conhecido em tempo de compilação.

Por exemplo, uma API de serviço da Web pública retorna o objeto JSON a seguir, que descreve algumas informações sobre um usuário do serviço.

{"personal": {"name": "Paul", "age": 23, "height": 1.7, "isSingle": true, "luckyNumbers": [5,17,21]}, "favoriteBands": ["Band ABC", "Band XYZ"]}

Para desserializar esse objeto, um cliente WCF deve implementar os seguintes tipos definidos pelo usuário.

[DataContract]
public class MemberProfile
 {
     [DataMember]
     public PersonalInfo personal;

     [DataMember]
     public string[] favoriteBands;
 }

 [DataContract]
public class PersonalInfo
 {
     [DataMember]
     public string name;

     [DataMember]
     public int age;

     [DataMember]
     public double height;

     [DataMember]
     public bool isSingle;

     [DataMember]
     public int[] luckyNumbers;
 }

Isso pode ser complicado, especialmente se o cliente precisar manipular mais de um tipo de objeto JSON.

O tipo JsonObject fornecido por este exemplo apresenta uma representação com tipagem fraca do objeto JSON desserializado. JsonObject baseia-se no mapeamento natural entre objetos JSON e dicionários .NET Framework e no mapeamento entre matrizes JSON e matrizes .NET Framework. O código a seguir mostra o tipo JsonObject.

// Instantiation of JsonObject json omitted

string name = json["root"]["personal"]["name"];
int age = json["root"]["personal"]["age"];
double height = json["root"]["personal"]["height"];
bool isSingle = json["root"]["personal"]["isSingle"];
int[] luckyNumbers = {
                                     json["root"]["personal"]["luckyNumbers"][0],
                                     json["root"]["personal"]["luckyNumbers"][1],
                                     json["root"]["personal"]["luckyNumbers"][2]
                                 };
string[] favoriteBands = {
                                        json["root"]["favoriteBands"][0],
                                        json["root"]["favoriteBands"][1]
                                    };

Observe que você pode "navegar" objetos e matrizes JSON sem a necessidade de declarar seu tipo em tempo de compilação. Para obter uma explicação do requisito para o objeto ["root"] de nível superior, consulte o tópico Mapeamento entre JSON e XML.

Observação

A classe JsonObject é fornecida apenas como exemplo. Ele não foi completamente testado e não deve ser usado em ambientes de produção. Uma implicação óbvia da serialização JSON com tipagem fraca é a falta de segurança de tipo ao trabalhar com JsonObject.

Para usar o tipo JsonObject, o contrato de operação do cliente deve usar Message como seu tipo de retorno.

[ServiceContract]
    interface IClientSideProfileService
    {
        // There is no need to write a DataContract for the complex type returned by the service.
        // The client will use a JsonObject to browse the JSON in the received message.

        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json)]
        Message GetMemberProfile();
    }

O JsonObject é então instanciado conforme mostrado no código a seguir.

// Code to instantiate IClientSideProfileService channel omitted…

// Make a request to the service and obtain the Json response
XmlDictionaryReader reader = channel.GetMemberProfile().GetReaderAtBodyContents();

// Go through the Json as though it is a dictionary. There is no need to map it to a .NET CLR type.
JsonObject json = new JsonObject(reader);

O construtor JsonObject recebe um XmlDictionaryReader, que é obtido por meio do método GetReaderAtBodyContents. O leitor contém uma representação XML da mensagem JSON recebida pelo cliente. Para obter mais informações, consulte o tópico Mapeamento entre JSON e XML.

O programa produz a seguinte saída:

Service listening at http://localhost:8000/.
To view the JSON output from the sample, navigate to http://localhost:8000/GetMemberProfile
This is Paul's page. I am 23 years old and I am 1.7 meters tall.
I am single.
My lucky numbers are 5, 17, and 21.
My favorite bands are Band ABC and Band XYZ.

Para configurar, compilar, e executar o exemplo

  1. Verifique se você executou o Procedimento de instalação única para os exemplos do Windows Communication Foundation.

  2. Crie a solução WeaklyTypedJson.sln conforme descrito em Criando os exemplos do Windows Communication Foundation.

  3. Execute a solução.