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;
}