Определение поведения клиента Run-Time

Клиенты Windows Communication Foundation (WCF), такие как службы Windows Communication Foundation (WCF), можно настроить для изменения поведения среды выполнения в соответствии с клиентским приложением. Три атрибута доступны для указания поведения среды выполнения клиента. Дуплексные объекты обратного вызова клиента могут использовать CallbackBehaviorAttribute и CallbackDebugBehavior атрибуты для изменения поведения среды выполнения. Другой атрибут ClientViaBehaviorможно использовать для разделения логического назначения от непосредственного сетевого назначения. Кроме того, типы обратного вызова дуплексного клиента могут использовать некоторые служебные поведения. Дополнительные сведения см. в разделе "Указание поведения службы Run-Time".

Использование атрибута CallbackBehaviorAttribute

Вы можете настроить или расширить поведение выполнения реализации контракта обратного вызова в клиентском приложении с помощью CallbackBehaviorAttribute класса. Этот атрибут выполняет аналогичную функцию для класса обратного вызова, как класс ServiceBehaviorAttribute, за исключением особенностей поведения и настроек транзакции.

Класс CallbackBehaviorAttribute должен быть применён к классу, реализующему контракт обратного вызова. Если применяется к реализации контракта недуплексного типа, InvalidOperationException исключение вызывается во время выполнения. В следующем примере кода показан CallbackBehaviorAttribute класс объекта обратного вызова, который использует SynchronizationContext объект для определения потока для маршалирования, ValidateMustUnderstand свойство для обеспечения проверки сообщений и IncludeExceptionDetailInFaults свойство, возвращающее исключения в виде объектов FaultException в службу для целей отладки.

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

Использование CallbackDebugBehavior для активации потока информации о контролируемых исключениях

Поток сведений об управляемом исключении можно включить в объект обратного вызова клиента обратно в службу для отладки, установив свойство IncludeExceptionDetailInFaults либо программно, либо из файла конфигурации приложения.

Возврат сведений об управляемом исключении службам может быть угрозой безопасности, так как сведения об исключении предоставляют сведения о внутренней реализации клиента, которую могут использовать несанкционированные службы. Кроме того, хотя CallbackDebugBehavior свойства также могут быть заданы программным способом, при развертывании можно легко забыть отключить IncludeExceptionDetailInFaults .

Из-за проблем безопасности настоятельно рекомендуется:

  • Для задания значения IncludeExceptionDetailInFaults свойства trueиспользуется файл конфигурации приложения.

  • Это можно сделать только в управляемых сценариях отладки.

В следующем примере кода показан файл конфигурации клиента, который указывает WCF возвращать сведения об управляемом исключении из объекта обратного вызова клиента в сообщениях 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>

Использование поведения ClientViaBehavior

Вы можете использовать поведение ClientViaBehavior для указания унифицированного идентификатора ресурса, для которого должен быть создан транспортный канал. Используйте это поведение, если непосредственное назначение сети не является предполагаемым обработчиком сообщения. Это позволяет многократные переходы, когда вызывающее приложение не обязательно знает конечный адрес назначения или когда заголовок назначения Via не является адресом.

См. также