指定客户端运行时行为

Windows Communication Foundation (WCF) 客户端(如 Windows Communication Foundation (WCF) 服务)可以配置为修改运行时行为以适应客户端应用程序。 有三个属性可用于指定客户端运行时行为。 双工客户端回调对象可以使用 CallbackBehaviorAttributeCallbackDebugBehavior 属性修改其运行时行为。 另一个属性 ClientViaBehavior 可用于将逻辑目标与直接网络目标分开。 此外,双工客户端回调类型可以使用某些服务端行为。 有关详细信息,请参阅指定服务运行时行为

使用 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 属性设置为 true

将托管异常信息返回到服务可能存在安全风险,因为异常详细信息会公开与内部客户端实现有关的信息,而未经授权的服务可能会使用这些信息。 此外,虽然 CallbackDebugBehavior 属性也可以通过编程方式进行设置,但在部署时容易忘记禁用 IncludeExceptionDetailInFaults

由于涉及到一些安全问题,因此强烈建议您:

下面的代码示例演示一个客户端配置文件,该文件指示 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 标头不是地址时,使用此行为可启用多跃点对话。

请参阅