指定客户端运行时行为
与 Windows Communication Foundation (WCF) 服务相似,可以对 Windows Communication Foundation (WCF) 客户端进行配置以修改运行时行为,以便适合客户端应用程序的需要。有三个属性可用于指定客户端运行时行为。双工客户端回调对象可以使用 CallbackBehaviorAttribute 和 CallbackDebugBehavior 属性修改其运行时行为。另一个属性 ClientViaBehavior 可用于将逻辑目标与直接网络目标分开。此外,双工客户端回调类型可以使用某些服务端行为。有关更多信息,请参见 指定服务运行时行为.
使用 CallbackBehaviorAttribute
可以使用 CallbackBehaviorAttribute 类来配置或扩展客户端应用程序中回调协定实现的执行行为。此属性为回调类和 ServiceBehaviorAttribute 类执行相似的功能,不同之处在于实例化行为和事务设置。
必须将 CallbackBehaviorAttribute 类应用于实现回调协定的类。如果将其应用于非双工协定实现,则会在运行时引发 InvalidOperationException 异常。下面的代码示例演示回调对象上的一个 CallbackBehaviorAttribute 类,该类使用 SynchronizationContext 对象确定要封送到的线程,使用 ValidateMustUnderstand 属性强制执行消息验证,并使用 IncludeExceptionDetailInFaults 属性将异常作为 FaultException 对象返回给服务以便进行调试。
Imports Microsoft.VisualBasic
Imports System
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
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();
}
}
}
使用 CallbackDebugBehavior 启用托管异常信息流
可以在客户端回调对象中启用托管异常信息流,使异常信息流回到服务以便进行调试,方法是以编程方式或从应用程序配置文件中将 IncludeExceptionDetailInFaults 属性设置为 true。
将托管异常信息返回到服务可能存在安全风险,因为异常详细信息会公开与内部客户端实现有关的信息,而未经授权的服务可能会使用这些信息。此外,虽然 CallbackDebugBehavior 属性也可以通过编程方式进行设置,但在部署时容易忘记禁用 IncludeExceptionDetailInFaults。
由于涉及到一些安全问题,因此强烈建议您:
使用应用程序配置文件将 IncludeExceptionDetailInFaults 属性的值设置为 true。
仅在受控调试方案中才能这样做。
下面的代码示例演示一个客户端配置文件,该文件指示 WCF 从 SOAP 消息中的客户端回调对象返回托管异常信息。
使用 ClientViaBehavior 行为
可以使用 ClientViaBehavior 行为指定应为其创建传输通道的统一资源标识符。当直接网络目标不是消息的预期处理者时,可使用此行为。当调用应用程序不需要知道最终目标时,或者当目标 Via 标头不是地址时,使用此行为可启用多跃点对话。