Teilen über


Spezifikation des Kunden-Run-Time-Verhaltens

Windows Communication Foundation (WCF)-Clients wie Windows Communication Foundation (WCF)-Dienste können so konfiguriert werden, dass das Laufzeitverhalten entsprechend der Clientanwendung geändert wird. Zur Angabe des Clientlaufzeitverhaltens stehen drei Attribute zur Verfügung. Duplex-Client-Rückrufobjekte können die Attribute CallbackBehaviorAttribute und CallbackDebugBehavior verwenden, um ihr Laufzeitverhalten zu ändern. Das andere Attribut, ClientViaBehavior, kann verwendet werden, um das logische Ziel vom unmittelbaren Netzwerkziel zu trennen. Außerdem können Duplexclient-Rückruftypen Teile des Dienstseitenverhaltens verwenden. Weitere Informationen finden Sie unter Angeben des Dienst-Run-Time Verhaltens.

Verwenden des CallbackBehaviorAttribute

Sie können das Ausführungsverhalten einer Rückrufvertragsimplementierung in einer Clientanwendung mithilfe der CallbackBehaviorAttribute Klasse konfigurieren oder erweitern. Dieses Attribut erfüllt eine ähnliche Funktion für die Rückrufklasse wie die ServiceBehaviorAttribute-Klasse, mit Ausnahme des Instanzierungsverhaltens und der Transaktionseinstellungen.

Die CallbackBehaviorAttribute Klasse muss auf die Klasse angewendet werden, die den Rückrufvertrag implementiert. Wenn sie auf eine nichtduplexe Vertragsimplementierung angewendet wird, wird zur Laufzeit eine InvalidOperationException Ausnahme ausgelöst. Das folgende Codebeispiel zeigt eine CallbackBehaviorAttribute Klasse für ein Rückrufobjekt, das das SynchronizationContext Objekt verwendet, um den Thread zu bestimmen, auf den marshallt wird, die ValidateMustUnderstand Eigenschaft zum Erzwingen der Nachrichtenüberprüfung und die IncludeExceptionDetailInFaults Eigenschaft, um Ausnahmen als FaultException Objekte zum Dienst für Debuggingzwecke zurückzugeben.

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

Verwenden von CallbackDebugBehavior zum Aktivieren des Flusses verwalteter Ausnahmeinformationen

Sie können den Fluss verwalteter Ausnahmeinformationen in einem Client-Rückrufobjekt zurück zum Dienst zum Debuggen aktivieren, indem Sie die IncludeExceptionDetailInFaults-Eigenschaft entweder programmgesteuert oder aus einer Anwendungskonfigurationsdatei auf true festlegen.

Das Zurückgeben verwalteter Ausnahmeinformationen an Dienste kann ein Sicherheitsrisiko darstellen, da Ausnahmedetails Informationen zur internen Clientimplementierung verfügbar machen, die nicht autorisierte Dienste verwenden könnten. Darüber hinaus können die CallbackDebugBehavior Eigenschaften zwar auch programmgesteuert festgelegt werden, aber es kann leicht sein, zu vergessen, IncludeExceptionDetailInFaults bei der Bereitstellung zu deaktivieren.

Aufgrund der sicherheitsrelevanten Probleme wird dringend empfohlen, folgendes zu beachten:

  • Sie verwenden eine Anwendungskonfigurationsdatei, um den Wert der IncludeExceptionDetailInFaults-Eigenschaft auf true festzulegen.

  • Dies geschieht nur in kontrollierten Debugszenarien.

Das folgende Codebeispiel zeigt eine Clientkonfigurationsdatei, die WCF anweist, verwaltete Ausnahmeinformationen aus einem Clientrückrufobjekt in SOAP-Nachrichten zurückzugeben.

  <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>

Verwenden des ClientViaBehavior-Verhaltens

Sie können das ClientViaBehavior Verhalten verwenden, um den Uniform Resource Identifier anzugeben, für den der Transportkanal erstellt werden soll. Verwenden Sie dieses Verhalten, wenn das direkte Netzwerkziel nicht der beabsichtigte Prozessor der Nachricht ist. Dies ermöglicht mehrstufige Unterhaltungen, wenn die aufrufende Anwendung nicht unbedingt das ultimative Ziel kennt oder wenn der Ziel-Via-Header keine Adresse ist.

Siehe auch