Udostępnij za pośrednictwem


Określanie zachowania klienta w czasie wykonywania

Klienci programu Windows Communication Foundation (WCF), tacy jak usługi Windows Communication Foundation (WCF), można skonfigurować tak, aby modyfikować zachowanie czasu wykonywania zgodnie z aplikacją kliencją. Do określania zachowania klienta w czasie wykonywania są dostępne trzy atrybuty. Dwukierunkowe obiekty wywołania zwrotnego klienta mogą używać CallbackBehaviorAttribute atrybutów i CallbackDebugBehavior do modyfikowania ich zachowania w czasie wykonywania. Inny atrybut , ClientViaBehaviormoże służyć do oddzielenia logicznego miejsca docelowego od najbliższego miejsca docelowego sieci. Ponadto typy wywołań zwrotnych klientów dwukierunkowych mogą używać niektórych zachowań po stronie usługi. Aby uzyskać więcej informacji, zobacz Określanie zachowania czasu wykonywania usługi.

Używanie elementu CallbackBehaviorAttribute

Możesz skonfigurować lub rozszerzyć zachowanie wykonywania implementacji kontraktu wywołania zwrotnego w aplikacji klienckiej CallbackBehaviorAttribute przy użyciu klasy . Ten atrybut wykonuje podobną funkcję dla klasy wywołania zwrotnego jako ServiceBehaviorAttribute klasy, z wyjątkiem zachowania instancing i ustawień transakcji.

Klasa CallbackBehaviorAttribute musi być stosowana do klasy implementujące kontrakt wywołania zwrotnego. W przypadku zastosowania do implementacji kontraktu nieduplex wyjątek InvalidOperationException jest zgłaszany w czasie wykonywania. Poniższy przykład kodu przedstawia klasę CallbackBehaviorAttribute w obiekcie wywołania zwrotnego, który używa SynchronizationContext obiektu do określania wątku do marshalingu, ValidateMustUnderstand właściwości wymuszania weryfikacji komunikatów oraz IncludeExceptionDetailInFaults właściwości zwracania wyjątków jako FaultException obiektów do usługi na potrzeby debugowania.

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

Używanie funkcji CallbackDebugBehavior w celu włączenia przepływu informacji o wyjątkach zarządzanych

Możesz włączyć przepływ informacji o wyjątkach zarządzanych w obiekcie wywołania zwrotnego klienta z powrotem do usługi na potrzeby debugowania, ustawiając IncludeExceptionDetailInFaults właściwość na true programowe lub z pliku konfiguracji aplikacji.

Zwracanie informacji o wyjątkach zarządzanych do usług może stanowić zagrożenie bezpieczeństwa, ponieważ szczegóły wyjątku ujawniają informacje o wewnętrznej implementacji klienta, z których mogą korzystać nieautoryzowane usługi. Ponadto, mimo że CallbackDebugBehavior właściwości można również ustawić programowo, można łatwo zapomnieć o wyłączeniu IncludeExceptionDetailInFaults podczas wdrażania.

Ze względu na związane z tym problemy z zabezpieczeniami zdecydowanie zaleca się:

  • Plik konfiguracji aplikacji służy do ustawiania wartości IncludeExceptionDetailInFaults właściwości na true.

  • Można to zrobić tylko w kontrolowanych scenariuszach debugowania.

Poniższy przykład kodu przedstawia plik konfiguracji klienta, który instruuje program WCF, aby zwracał informacje o wyjątkach zarządzanych z obiektu wywołania zwrotnego klienta w komunikatach PROTOKOŁU 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>

Używanie zachowania ClientViaBehavior

Możesz użyć ClientViaBehavior tego zachowania, aby określić jednolity identyfikator zasobu, dla którego ma zostać utworzony kanał transportu. Użyj tego zachowania, gdy bezpośrednie miejsce docelowe sieci nie jest zamierzonym procesorem komunikatu. Umożliwia to konwersacje wielokrotnego przeskoku, gdy aplikacja wywołująca nie musi znać ostatecznego miejsca docelowego lub gdy nagłówek docelowy Via nie jest adresem.

Zobacz też