A primeira etapa para a construção de um serviço WCF é a definição do contrato do serviço que, durante a escrita do código, é determinado pela criação de uma interface tradicional. Os métodos que são criados ali são, em tempo de execução, expostos através do WSDL para que os clientes possam consumí-los.
Se criarmos uma referencia para o serviço a partir da IDE do Visual Studio ou do utilitário svcutil.exe, automaticamente um proxy será criado e podemos invocar os métodos a partir dele, com a impressão de que se estivéssemos chamando um método localmente mas que, durante a execução, uma mensagem é criada e enviada ao respectivo método remoto.
Mas e quando não temos o essa flexibilidade de criar o proxy (exemplo)? Como fazemos para invocar o um método disponibilizado pelo serviço? Felizmente podemos recorrer ao Fiddler ou até mesmo as classes HttpWebRequest e HttpWebResponse para efetuar a requisição, montando o cabeçalho e o corpo (SOAP) para invocar um determinado método do serviço. Esse procedimento permite a quem estiver consumindo, colocar o nome errado do método a ser invocado e, consequentemente, o seu serviço irá rejeitar a requisição.
Felizmente o WCF nos permite lidar com mensagens genéricas, ou seja, podemos criar um método que capturará toda e qualquer mensagem que não for encontrada no contrato do serviço. Para isso, basta definirmos a propriedade Action e ReplyAction do atributo OperationContractAttribute para “*”. Isso fará com que todas as mensagens não encontradas na definição do contrato, sejam encaminhadas para este método, em que podemos efetuar logging, notificações, etc. Abaixo um exemplo ilustra como proceder:
[OperationContract(Action=”*”, ReplyAction=”*”)]
Message ProcessRequest(Message msg);
É importante notar que o método recebe e também retorna uma instancia da classe Message. Esta classe representa a mensagem dentro do WCF. Além disso, também podemos usar esta mesma técnica quando utilizamos o modelo REST, só que agora, devemos definir a propriedade UriTemplate do o atributo WebGetAttribute para “*” e, assim como o OperationContractAttribute, consiga capturar todas mensagens não mapeadas/existentes.
[OperationContract]
[WebGet(UriTemplate=”*”)]
Message ProcessRequest(Message msg);