Especificando o comportamento de tempo de execução do cliente

Os clientes do Windows Communication Foundation (WCF), como os serviços do Windows Communication Foundation (WCF), podem ser configurados para modificar o comportamento em tempo de execução para se adequar ao aplicativo cliente. Três atributos estão disponíveis para especificar o comportamento em tempo de execução do cliente. Os objetos de retorno de chamada do cliente duplex podem usar os CallbackBehaviorAttribute atributos e CallbackDebugBehavior para modificar seu comportamento em tempo de execução. O outro atributo, ClientViaBehavior, pode ser usado para separar o destino lógico do destino de rede imediato. Além disso, os tipos de retorno de chamada do cliente duplex podem usar alguns dos comportamentos do lado do serviço. Para obter mais informações, consulte Especificando o comportamento em tempo de execução do serviço.

Usando o CallbackBehaviorAttribute

Você pode configurar ou estender o comportamento de execução de uma implementação de contrato de retorno de chamada em um aplicativo cliente usando a CallbackBehaviorAttribute classe. Esse atributo executa uma função semelhante para a classe de retorno de chamada como a ServiceBehaviorAttribute classe, com exceção do comportamento de instanciação e das configurações de transação.

A CallbackBehaviorAttribute classe deve ser aplicada à classe que implementa o contrato de retorno de chamada. Se aplicada a uma implementação de contrato não duplex, uma InvalidOperationException exceção é lançada em tempo de execução. O exemplo de código a seguir mostra uma CallbackBehaviorAttribute classe em um objeto de retorno de chamada que usa o SynchronizationContext objeto para determinar o thread para empacotar, a ValidateMustUnderstand propriedade para impor a validação de mensagem e a IncludeExceptionDetailInFaults propriedade para retornar exceções como FaultException objetos para o serviço para fins de depuração.

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Threading;

namespace Microsoft.WCF.Documentation
{
  [CallbackBehaviorAttribute(
   IncludeExceptionDetailInFaults= true,
    UseSynchronizationContext=true,
    ValidateMustUnderstand=true
  )]
  public class Client : SampleDuplexHelloCallback
  {
    AutoResetEvent waitHandle;

    public Client()
    {
      waitHandle = new AutoResetEvent(false);
    }

    public void Run()
    {
      // Picks up configuration from the configuration file.
      SampleDuplexHelloClient wcfClient
        = new SampleDuplexHelloClient(new InstanceContext(this), "WSDualHttpBinding_SampleDuplexHello");
      try
      {
        Console.ForegroundColor = ConsoleColor.White;
        Console.WriteLine("Enter a greeting to send and press ENTER: ");
        Console.Write(">>> ");
        Console.ForegroundColor = ConsoleColor.Green;
        string greeting = Console.ReadLine();
        Console.ForegroundColor = ConsoleColor.White;
        Console.WriteLine("Called service with: \r\n\t" + greeting);
        wcfClient.Hello(greeting);
        Console.WriteLine("Execution passes service call and moves to the WaitHandle.");
        this.waitHandle.WaitOne();
        Console.ForegroundColor = ConsoleColor.Blue;
        Console.WriteLine("Set was called.");
        Console.Write("Press ");
        Console.ForegroundColor = ConsoleColor.Red;
        Console.Write("ENTER");
        Console.ForegroundColor = ConsoleColor.Blue;
        Console.Write(" to exit...");
        Console.ReadLine();
      }
      catch (TimeoutException timeProblem)
      {
        Console.WriteLine("The service operation timed out. " + timeProblem.Message);
        Console.ReadLine();
      }
      catch (CommunicationException commProblem)
      {
        Console.WriteLine("There was a communication problem. " + commProblem.Message);
        Console.ReadLine();
      }
    }
    public static void Main()
    {
      Client client = new Client();
      client.Run();
    }

    public void Reply(string response)
    {
      Console.WriteLine("Received output.");
      Console.WriteLine("\r\n\t" + response);
      this.waitHandle.Set();
    }
  }
}

Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports System.Threading

Namespace Microsoft.WCF.Documentation
    <CallbackBehaviorAttribute(IncludeExceptionDetailInFaults:=True, UseSynchronizationContext:=True, ValidateMustUnderstand:=True)> _
    Public Class Client
        Implements SampleDuplexHelloCallback
        Private waitHandle As AutoResetEvent

        Public Sub New()
            waitHandle = New AutoResetEvent(False)
        End Sub

        Public Sub Run()
            ' Picks up configuration from the configuration file.
            Dim wcfClient As New SampleDuplexHelloClient(New InstanceContext(Me), "WSDualHttpBinding_SampleDuplexHello")
            Try
                Console.ForegroundColor = ConsoleColor.White
                Console.WriteLine("Enter a greeting to send and press ENTER: ")
                Console.Write(">>> ")
                Console.ForegroundColor = ConsoleColor.Green
                Dim greeting As String = Console.ReadLine()
                Console.ForegroundColor = ConsoleColor.White
                Console.WriteLine("Called service with: " & Constants.vbCrLf & Constants.vbTab & greeting)
                wcfClient.Hello(greeting)
                Console.WriteLine("Execution passes service call and moves to the WaitHandle.")
                Me.waitHandle.WaitOne()
                Console.ForegroundColor = ConsoleColor.Blue
                Console.WriteLine("Set was called.")
                Console.Write("Press ")
                Console.ForegroundColor = ConsoleColor.Red
                Console.Write("ENTER")
                Console.ForegroundColor = ConsoleColor.Blue
                Console.Write(" to exit...")
                Console.ReadLine()
            Catch timeProblem As TimeoutException
                Console.WriteLine("The service operation timed out. " & timeProblem.Message)
                Console.ReadLine()
            Catch commProblem As CommunicationException
                Console.WriteLine("There was a communication problem. " & commProblem.Message)
                Console.ReadLine()
            End Try
        End Sub
        Public Shared Sub Main()
            Dim client As New Client()
            client.Run()
        End Sub

        Public Sub Reply(ByVal response As String) Implements SampleDuplexHelloCallback.Reply
            Console.WriteLine("Received output.")
            Console.WriteLine(Constants.vbCrLf & Constants.vbTab & response)
            Me.waitHandle.Set()
        End Sub
    End Class
End Namespace

Usando CallbackDebugBehavior para habilitar o fluxo de informações de exceção gerenciada

Você pode habilitar o fluxo de informações de exceção gerenciadas em um objeto de retorno de chamada do cliente de volta ao serviço para fins de depuração definindo a IncludeExceptionDetailInFaults propriedade como true programaticamente ou a partir de um arquivo de configuração do aplicativo.

Retornar informações de exceção gerenciada para serviços pode ser um risco de segurança porque os detalhes da exceção expõem informações sobre a implementação do cliente interno que serviços não autorizados poderiam usar. Além disso, embora as CallbackDebugBehavior propriedades também possam ser definidas programaticamente, pode ser fácil esquecer de desativar IncludeExceptionDetailInFaults durante a implantação.

Devido às questões de segurança envolvidas, recomenda-se vivamente que:

  • Use um arquivo de configuração do aplicativo para definir o IncludeExceptionDetailInFaults valor da propriedade como true.

  • Você faz isso apenas em cenários de depuração controlada.

O exemplo de código a seguir mostra um arquivo de configuração do cliente que instrui o WCF a retornar informações de exceção gerenciadas de um objeto de retorno de chamada do cliente em mensagens SOAP.

  <client>
      <endpoint 
        address="http://localhost:8080/DuplexHello" 
        binding="wsDualHttpBinding"
        bindingConfiguration="WSDualHttpBinding_SampleDuplexHello"
        contract="SampleDuplexHello" 
        name="WSDualHttpBinding_SampleDuplexHello"
        behaviorConfiguration="enableCallbackDebug">
      </endpoint>
  </client>
<behaviors>
  <endpointBehaviors>
    <behavior name="enableCallbackDebug">
      <callbackDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </endpointBehaviors>
</behaviors>

Usando o comportamento ClientViaBehavior

Você pode usar o ClientViaBehavior comportamento para especificar o Uniform Resource Identifier para o qual o canal de transporte deve ser criado. Use esse comportamento quando o destino imediato da rede não é o processador pretendido da mensagem. Isso permite conversas de vários saltos quando o aplicativo de chamada não sabe necessariamente o destino final ou quando o cabeçalho de destino Via não é um endereço.

Consulte também