Compartilhar via


Especificando a execução do cliente- Comportamento do tempo

Os clientes do WCF (Windows Communication Foundation), assim como os serviços do WCF (Windows Communication Foundation), podem ser configurados para modificar o comportamento de tempo de execução para atender ao aplicativo cliente. Três atributos estão disponíveis para especificar o comportamento co cliente em tempo de execução. Objetos de retorno de chamada de cliente duplex podem usar os atributos CallbackBehaviorAttribute 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 de cliente duplex podem usar alguns dos comportamentos do lado do serviço. Para obter mais informações, consulte Especificar o comportamento do cliente em tempo de execução.

Usar 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 classe CallbackBehaviorAttribute. Esse atributo executa uma função semelhante para a classe de retorno de chamada como a classe ServiceBehaviorAttribute, com exceção do comportamento de instanciação e das configurações de transação.

A classe CallbackBehaviorAttribute deve ser aplicada à classe que implementa o contrato de retorno de chamada. Se aplicado a uma implementação de contrato não duplex, uma exceção InvalidOperationException é gerada em tempo de execução. O exemplo de código a seguir mostra uma classe CallbackBehaviorAttribute em um objeto de retorno de chamada que usa o objeto SynchronizationContext para determinar a conversa para a qual realizar marshal, a propriedade ValidateMustUnderstand para impor a validação de mensagem e a propriedade IncludeExceptionDetailInFaults para retornar exceções como objetos FaultException 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

Usar o CallbackDebugBehavior para habilitar o fluxo de informações de exceção gerenciadas

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 propriedade IncludeExceptionDetailInFaults como true, seja programaticamente ou a partir de um arquivo de configuração de aplicativo.

Retornar informações de exceção gerenciadas aos serviços pode ser um risco para a segurança, pois os detalhes da exceção expõem informações sobre a implementação interna do cliente que podem ser usadas por clientes não autorizados. Além disso, embora as propriedades CallbackDebugBehavior também possam ser definidas programaticamente, pode ser fácil esquecer de desabilitar IncludeExceptionDetailInFaults ao implantar.

Devido aos problemas de segurança envolvidos, é altamente recomendável que:

  • Você use um arquivo de configuração de aplicativo para definir o valor da propriedade IncludeExceptionDetailInFaults como true.

  • Você faça isso somente 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>

Usar o comportamento ClientViaBehavior

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

Confira também