指定用戶端執行階段行為
Windows Communication Foundation (WCF) 用戶端,例如 Windows Communication Foundation (WCF) 服務,可以設定為修改應用程式行為以符合用戶端應用程式。 指定用戶端執行階段行為時有三個屬性可供使用。 雙工用戶端回呼物件可以使用 CallbackBehaviorAttribute 和 CallbackDebugBehavior 屬性來修改其執行階段行為。 而另一個屬性 ClientViaBehavior 則可用來區隔邏輯目的和立即網路目的。 此外,雙工用戶端回呼類型也可使用一些服務端的行為。 如需詳細資訊,請參閱指定服務執行階段行為。
使用 CallbackBehaviorAttribute
您可以使用 CallbackBehaviorAttribute 類別,即可設定或擴充用戶端應用程式中回呼合約實作的執行行為。 這個屬性對回呼類別執行的函式類似於 ServiceBehaviorAttribute 類別,而執行個體化行為和交易設定則為其例外。
CallbackBehaviorAttribute 類別必須套用至實作回呼合約的類別。 如果套用至非雙工合約實作,便會在執行階段擲回 InvalidOperationException 例外狀況 (Exception)。 下列程式碼範例會顯示回呼物件上的 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 啟用 Managed 例外狀況資訊的流動
如果您以程式設計方式或從應用程式組態檔將 IncludeExceptionDetailInFaults 屬性設定為 true
,則可以讓用戶端回呼物件中的 Managed 例外狀況資訊的流動回到服務,以達偵錯的目的。
將 Managed 例外狀況資訊傳回服務可能導致安全性風險,因為例外狀況詳細資料會公開未授權的服務可使用的內部用戶端實作相關資訊。 此外,雖然也能以程式設計方式設定 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
標頭不是位址時,這個行為可啟用多重躍點交談。