(De)Serialização de Objetos em WCF


Objetos que são enviados ou recebidos em serviços WCF sofrem o processo de serialização e deserialização. Quando os métodos de um determinado serviço recebem ou devolvem objetos complexos, então estes também sofrem o mesmo processo.

Quando o cliente faz a referencia para este serviço, a IDE do Visual Studio .NET é capaz de ler os metadados e criar uma representação desta classe do lado do cliente, podendo agora, instanciar e enviar este objeto para um determinado método, ou ainda, receber de um dos métodos do serviço tal objeto. Como temos uma classe criada do lado do cliente, se ele desejar, o mesmo pode adicionar novas propriedades a mesma e, consequentemente, quando a instancia dessa classe for submetida para o serviço, essas novas propriedades não encontrarão uma correspondente do lado do servidor durante o processo de deserialização.

Felizmente a Microsoft disponibilizou a interface IExtensibleDataObject que fornece uma estrutura para armazenar os dados extras (propriedades marcadas com o atributo DataContractAttribute) encontrados durante o processo de deserialização. Essa interface fornece uma única propriedade chamada ExtensionData. Segundo as boas práticas, sempre é importante que se implemente essa interface em todos as classes que são decoradas com o atributo DataContractAttribute. Se notarmos, independentemente de implementar essa interface ou não nas classes que estão no serviço, ao fazermos a referencia no projeto cliente, automaticamente, a classe criada pela IDE já implementa tal interface, justamente para permitir que o servidor mande novas propriedades que o cliente ainda não possui.

O fato de implementar essa interface não quer dizer que voce obrigatoriamente precisa manter esses dados. É perfeitamente possível desconsiderar qualquer propriedade, caso não encontre uma correspondente durante a deserialização. Para isso, voce tem algumas possibilidades. A primeira delas é definir para True a propriedade IgnoreExtensionDataObject do atributo ServiceBehaviorAttribute, o que refletirá em todas as operações que o serviço fornece. O exemplo abaixo ilustra isso:

[ServiceBehavior(IgnoreExtensionDataObject = true)]
public class Usuarios : IUsuario { }

A outra alternativa é via arquivo de configuração, que te dará uma maior flexibilidade, já que voce pode ligar ou desligar sem precisar recompilar a aplicação. Para isso, utilizamos o elemento dataContractSerializer:

<dataContractSerializer ignoreExtensionDataObject=”true” />

Finalmente, se desejar aplicar esse comportamento apenas para um determinado método, precisamos recorrer a classe DataContractSerializerOperationBehavior. Mas antes de mais nada, precisamos inicialmente recuperar a operação que desejamos manipular e, em seguida, criarmos a instancia da classe DataContractSerializerOperationBehavior e, para finalizar, adicionamos a mesma na coleção de behaviors da operação em questão. O trecho de código abaixo ilustra esse processo:

private static void SetIgnoreExtensionDataObject(ServiceHost host, string operationName, bool ignore)
{
    ContractDescription cd = host.Description.Endpoints[0].Contract;
    OperationDescription od = cd.Operations.Find(operationName);

    DataContractSerializerOperationBehavior b =
        od.Behaviors.Find<DataContractSerializerOperationBehavior>();

    if (b == null)
    {
        b = new DataContractSerializerOperationBehavior(od);
        od.Behaviors.Add(b);
    }

    b.IgnoreExtensionDataObject = ignore;
}

Anúncios

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s