Compartilhar via


Especificando o Comportamento do Cliente Run-Time

Clientes do Windows Communication Foundation (WCF), como os serviços do Windows Communication Foundation (WCF), podem ser configurados para modificar o comportamento de runtime para atender ao aplicativo cliente. Três atributos estão disponíveis para especificar o comportamento do runtime do cliente. Objetos de retorno de chamada do cliente Duplex podem usar os atributos CallbackBehaviorAttribute e CallbackDebugBehavior para modificar seu comportamento de tempo de execução. O outro atributo, ClientViaBehaviorpode 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 Especificando o comportamento de serviço Run-Time.

Usando o atributo CallbackBehavior

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 classe ServiceBehaviorAttribute, com exceção do comportamento de instanciação e das configurações de transação.

A CallbackBehaviorAttribute classe deve ser aplicada na classe que implementa o contrato de callback. Se aplicado a uma implementação de contrato nonduplex, uma exceção InvalidOperationException será lançada em runtime. 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 gerenciada aos serviços pode ser um risco de segurança porque os detalhes da exceção expõem informações sobre a implementação interna do cliente 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 desabilitar IncludeExceptionDetailInFaults ao implantar.

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

  • Você usa um arquivo de configuração de aplicativo para definir o valor da IncludeExceptionDetailInFaults propriedade 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 ClientViaBehavior comportamento 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. 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