Sdílet prostřednictvím


Určení chování klienta Run-Time

Klienti Windows Communication Foundation (WCF), jako jsou služby WCF (Windows Communication Foundation), je možné nakonfigurovat tak, aby upravovaly chování modulu runtime tak, aby vyhovovaly klientské aplikaci. Pro určení chování modulu runtime klienta jsou k dispozici tři atributy. Objekty duplexního klienta mohou použít atribut CallbackBehaviorAttribute a CallbackDebugBehavior ke změně jejich chování za běhu. Druhý atribut , ClientViaBehaviorlze použít k oddělení logického cíle od bezprostředního síťového cíle. Navíc mohou typy zpětného volání duplexního klienta využívat některé chování na straně služby. Další informace naleznete v tématu Určení chování služby Run-Time.

Použití CallbackBehaviorAttribute

Pomocí třídy můžete nakonfigurovat nebo rozšířit chování provádění implementace kontraktu zpětného volání v klientské aplikaci CallbackBehaviorAttribute . Tento atribut provádí podobnou funkci pro třídu zpětného volání jako ServiceBehaviorAttribute třída, s výjimkou chování instance a nastavení transakcí.

Třída CallbackBehaviorAttribute musí být použita na třídu, která implementuje kontrakt zpětného volání. Pokud je použita na ne-duplexní implementaci kontraktu, je za běhu vyvolána výjimka InvalidOperationException. Následující příklad kódu ukazuje CallbackBehaviorAttribute třídu na objektu zpětného volání, která používá SynchronizationContext objekt k stanovení vlákna, do kterého se má objekt zařadit, ValidateMustUnderstand vlastnost k vynucení ověření zpráv a IncludeExceptionDetailInFaults vlastnost k vrácení výjimek jako FaultException objektů službě pro účely ladění.

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

Povolení toku informací o spravovaných výjimce pomocí callbackDebugBehavior

Tok informací o spravovaných výjimkách, které jsou z objektu zpětného volání klienta přenášeny zpět do služby kvůli ladění, můžete povolit nastavením vlastnosti IncludeExceptionDetailInFaults na true buď prostřednictvím kódu, nebo z konfiguračního souboru aplikace.

Vrácení informací o spravovaných výjimce službám může být bezpečnostní riziko, protože podrobnosti o výjimce zveřejňují informace o interní implementaci klienta, kterou by mohly používat neoprávněné služby. Kromě toho, i když CallbackDebugBehavior je možné vlastnosti nastavit také programově, může být při nasazování snadné zapomenout zakázat IncludeExceptionDetailInFaults .

Vzhledem k problémům se zabezpečením důrazně doporučujeme:

  • Konfigurační soubor aplikace slouží k nastavení hodnoty IncludeExceptionDetailInFaults vlastnosti na true.

  • Provedete to pouze ve scénářích řízeného ladění.

Následující příklad kódu ukazuje konfigurační soubor klienta, který dává WCF pokyn, aby vrátil spravované informace o výjimce z objektu zpětného volání klienta ve zprávách 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>

Použití chování ClientViaBehavior

Pomocí chování ClientViaBehavior můžete určit identifikátor jednotného prostředku, pro který se má vytvořit transportní kanál. Toto chování použijte, pokud okamžitý síťový cíl není zamýšleným procesorem zprávy. To umožňuje vícehopové konverzace, když volající aplikace nemusí nutně znát konečný cíl nebo když cílová Via hlavička není adresa.

Viz také