WCF 用戶端概觀
本節描述用戶端應用程式的功能、如何設定、建立和使用 Windows Communication Foundation (WCF) 用戶端,以及如何保護用戶端應用程式。
使用 WCF 用戶端物件
用戶端應用程式為受控應用程式,可使用 WCF 用戶端與其他應用程式通訊。 如要針對 WCF 服務建立用戶端應用程式,需要進行下列步驟:
取得服務端點的服務合約、繫結和位址資訊。
使用該資訊建立 WCF 用戶端。
呼叫作業。
關閉 WCF 用戶端物件。
下列各節將討論這些步驟,並簡要介紹以下問題:
處理錯誤。
設定和保護用戶端。
建立雙工服務的回呼物件。
非同步呼叫服務。
透過用戶端通道呼叫服務。
取得服務合約、繫結和位址
在 WCF 中,服務及用戶端模型合約會使用受控屬性、介面及方法。 若要在用戶端應用程式中連接到服務,您必須取得服務合約的類型資訊。 一般而言,您可以使用 ServiceModel 中繼資料公用程式工具 (Svcutil.exe) 來取得服務合約的類型資訊。 此公用程式會從服務下載中繼資料,將該中繼資料轉換為您所選語言的受控原始程式碼檔案,並建立可用於設定 WCF 用戶端物件的用戶端應用程式組態檔。 例如,若您要建立 WCF 用戶端物件以叫用 MyCalculatorService
,且您知道該服務的中繼資料是發佈於 http://computerName/MyCalculatorService/Service.svc?wsdl
,則下列程式碼範例會示範如何使用 Svcutil.exe 取得 ClientCode.vb
檔案,該檔案會包含以受控程式碼撰寫的服務合約。
svcutil /language:vb /out:ClientCode.vb /config:app.config http://computerName/MyCalculatorService/Service.svc?wsdl
您可以將這段合約程式碼編譯成用戶端應用程式,或編譯成另一個組件,用戶端應用程式能接著使用該組件來建立 WCF 用戶端物件。 您可以使用組態檔來設定用戶端物件,以便正確連接到服務。
如需此流程的範例,請參閱操作說明:建立用戶端。 如需合約的詳細資訊,請參閱合約。
建立 WCF 用戶端物件
WCF 用戶端為本機物件,會以用戶端可用來與遠端服務通訊的形式代表 WCF 服務。 WCF 用戶端類型會實作目標服務合約,因此當您建立並設定 WCF 用戶端時,就可以直接使用用戶端物件來叫用服務作業。 WCF 執行階段會將方法呼叫轉換為訊息並傳送至服務,然後接聽回覆,再將這些值作為傳回值或 out
或 ref
參數傳回給 WCF 用戶端物件。
您也可以使用 WCF 用戶端通道物件來與服務連線並加以使用。 如需詳細資料,請參閱 WCF 用戶端架構。
建立新的 WCF 物件
為說明 ClientBase<TChannel> 類別的使用方式,請假設已從服務應用程式產生下列簡單服務合約。
注意
若您是使用 Visual Studio 建立 WCF 用戶端,當您將服務參考新增至專案時,物件瀏覽器即會自動載入物件。
[System.ServiceModel.ServiceContractAttribute(
Namespace = "http://microsoft.wcf.documentation"
)]
public interface ISampleService
{
[System.ServiceModel.OperationContractAttribute(
Action = "http://microsoft.wcf.documentation/ISampleService/SampleMethod",
ReplyAction = "http://microsoft.wcf.documentation/ISampleService/SampleMethodResponse"
)]
[System.ServiceModel.FaultContractAttribute(
typeof(microsoft.wcf.documentation.SampleFault),
Action = "http://microsoft.wcf.documentation/ISampleService/SampleMethodSampleFaultFault"
)]
string SampleMethod(string msg);
}
若您並不是使用 Visual Studio,請檢查產生的合約程式碼,以找出擴充 ClientBase<TChannel> 和服務合約介面 ISampleService
的類型。 在這種情況下,該型別看起來類似下列程式碼:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class SampleServiceClient : System.ServiceModel.ClientBase<ISampleService>, ISampleService
{
public SampleServiceClient()
{
}
public SampleServiceClient(string endpointConfigurationName)
:
base(endpointConfigurationName)
{
}
public SampleServiceClient(string endpointConfigurationName, string remoteAddress)
:
base(endpointConfigurationName, remoteAddress)
{
}
public SampleServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress)
:
base(endpointConfigurationName, remoteAddress)
{
}
public SampleServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress)
:
base(binding, remoteAddress)
{
}
public string SampleMethod(string msg)
{
return base.Channel.SampleMethod(msg);
}
}
您可以將這個類別建立成本機物件,其方式是使用其中一個建構函式,然後加以設定,再用來連接到型別為 ISampleService
的服務。
建議您先建立 WCF 用戶端物件,然後在單一 try/catch 區塊內使用並關閉該物件。 請勿使用 using
陳述式 (在 Visual Basic 中為 Using
),因為其可能會遮蓋特定失敗模式中的例外狀況。 如需詳細資訊,請參閱下列各節以及使用 Close 和 Abort 釋出 WCF 用戶端資源。
合約、繫結和位址
您必須先設定用戶端物件,才可以建立 WCF 用戶端物件。 具體來說,就是必須有可使用的服務「端點」。 端點是服務合約、繫結和位址的組合 (如需端點的詳細資訊,請參閱端點:位址、繫結和合約 (部分機器翻譯))。一般而言,此資訊會位於用戶端應用程式組態檔的 <endpoint> 元素 (例如 Svcutil.exe 工具所產生的項目) 中,且會在您建立用戶端物件時自動載入。 這兩個 WCF 用戶端類型也具有多載,可讓您以程式設計的方式指定此資訊。
例如,針對前面範例中使用的 ISampleService
所產生的組態檔會包含下列端點資訊。
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ISampleService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:01:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8080/SampleService" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ISampleService" contract="ISampleService"
name="WSHttpBinding_ISampleService">
</endpoint>
</client>
</system.serviceModel>
</configuration>
這個組態檔會在 <client>
元素中指定目標端點。 如需了解如何使用多個目標端點的詳細資訊,請參閱 ClientBase<TChannel> 或 ChannelFactory<TChannel> 建構函式。
呼叫作業
建立並設定用戶端物件之後,請建立 try/catch 區塊,然後呼叫作業 (呼叫方式同本機物件),再關閉 WCF 用戶端物件。 當用戶端應用程式呼叫第一項作業時,WCF 會自動開啟基礎通道,而該基礎通道會在物件回收時關閉。 (或者,您也可以在呼叫其他作業之前或之後明確地開啟和關閉通道)。
例如,您若有下列服務合約:
namespace Microsoft.ServiceModel.Samples
{
using System;
using System.ServiceModel;
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);
}
}
Namespace Microsoft.ServiceModel.Samples
Imports System
Imports System.ServiceModel
<ServiceContract(Namespace:= _
"http://Microsoft.ServiceModel.Samples")> _
Public Interface ICalculator
<OperationContract> _
Function Add(n1 As Double, n2 As Double) As Double
<OperationContract> _
Function Subtract(n1 As Double, n2 As Double) As Double
<OperationContract> _
Function Multiply(n1 As Double, n2 As Double) As Double
<OperationContract> _
Function Divide(n1 As Double, n2 As Double) As Double
End Interface
您可以建立 WCF 用戶端物件並呼叫其方法,藉此呼叫作業,如同下列程式碼範例所示。 WCF 用戶端物件的開啟、呼叫和關閉都會發生在單一 try/catch 區塊內部。 如需詳細資訊,請參閱使用 WCF 用戶端存取服務和使用 Close 和 Abort 釋出 WCF 用戶端資源。
CalculatorClient wcfClient = new CalculatorClient();
try
{
Console.WriteLine(wcfClient.Add(4, 6));
wcfClient.Close();
}
catch (TimeoutException timeout)
{
// Handle the timeout exception.
wcfClient.Abort();
}
catch (CommunicationException commException)
{
// Handle the communication exception.
wcfClient.Abort();
}
處理錯誤
當開啟基礎用戶端通道 (無論是明確或是自動呼叫作業)、使用用戶端或通道物件來呼叫作業,或關閉基礎用戶端通道時,都可能會在用戶端應用程式中發生例外狀況。 除了要由作業傳回因 SOAP 錯誤而擲回的任何 System.TimeoutException 物件之外,建議您最少還要讓應用程式有能力處理可能發生的 System.ServiceModel.CommunicationException 和 System.ServiceModel.FaultException 例外狀況。 作業合約中指定的 SOAP 錯誤會針對用戶端應用程式引發為 System.ServiceModel.FaultException<TDetail>,其中的型別參數是 SOAP 錯誤的詳細類型。 如需在用戶端應用程式中處理錯誤情況的詳細資訊,請參閱傳送和接收錯誤。 如需示範如何在用戶端中處理錯誤的範例,請參閱預期的例外狀況。
設定和保護用戶端
設定用戶端時,通常是先從組態檔載入用戶端或通道物件的必要目標端點資訊;儘管可以透過用戶端建構函式和屬性,使用程式設計方式載入這項資訊, 但是為了啟用特定用戶端行為,並符合許多安全性案例的需要,您應該另外執行其他必要的設定步驟。
例如,服務合約的安全性需求會在服務合約介面中宣告;如果 Svcutil.exe 建立了組態檔,這個檔案通常應包含能夠支援服務安全性需求的繫結。 不過,在某些情況下,可能需要進行更多的安全性設定,例如設定用戶端認證。 如需設定 WCF 用戶端安全性的詳細資訊,請參閱保護用戶端。
此外,還可以在用戶端應用程式中啟用某些自訂修改,例如自訂執行階段行為。 如需了解如何設定自訂用戶端行為的詳細資訊,請參閱設定用戶端行為。
建立雙工服務的回呼物件
雙工服務會指定回呼合約,這是用戶端應用程式為了在服務根據合約需求進行呼叫時提供其所需之回呼物件而必須實作的合約。 雖然回呼物件並非完整的服務 (例如,您無法透過回呼物件啟始通道),但基於實作和組態設定的目的,不妨將它們視為一種服務。
雙工服務的用戶端必須:
實作回呼合約類別。
建立回呼合約實作類別的執行個體,並用其建立您傳遞至 WCF 用戶端建構函式的 System.ServiceModel.InstanceContext 物件。
叫用作業和處理作業回呼。
雙面 WCF 用戶端物件函式的運作方式類似於其非雙面的對應項目,但不同之處在於前者會公開支援回呼所需的功能,包含回呼服務的組態。
例如,您可以在回呼類別上使用 System.ServiceModel.CallbackBehaviorAttribute 屬性 (Attribute) 的屬性 (Property),控制回呼物件執行階段行為的各種層面。 此外,還可以使用 System.ServiceModel.Description.CallbackDebugBehavior 類別,讓例外狀況資訊回傳給呼叫回呼物件的服務。 如需詳細資訊,請參閱雙面服務。 如需完整範例,請參閱雙面。
在執行 Internet Information Services (IIS) 5.1 的 Windows XP 電腦上,雙工用戶端必須使用 System.ServiceModel.WSDualHttpBinding 類別來指定用戶端基底位址,否則會擲回例外狀況。 下列程式碼範例示範如何在程式碼中執行這項工作。
WSDualHttpBinding dualBinding = new WSDualHttpBinding();
EndpointAddress endptadr = new EndpointAddress("http://localhost:12000/DuplexTestUsingCode/Server");
dualBinding.ClientBaseAddress = new Uri("http://localhost:8000/DuplexTestUsingCode/Client/");
Dim dualBinding As New WSDualHttpBinding()
Dim endptadr As New EndpointAddress("http://localhost:12000/DuplexTestUsingCode/Server")
dualBinding.ClientBaseAddress = New Uri("http://localhost:8000/DuplexTestUsingCode/Client/")
下列程式碼範例示範如何在組態檔中執行這項工作。
<client>
<endpoint
name ="ServerEndpoint"
address="http://localhost:12000/DuplexUsingConfig/Server"
bindingConfiguration="WSDualHttpBinding_IDuplex"
binding="wsDualHttpBinding"
contract="IDuplex"
/>
</client>
<bindings>
<wsDualHttpBinding>
<binding
name="WSDualHttpBinding_IDuplex"
clientBaseAddress="http://localhost:8000/myClient/"
/>
</wsDualHttpBinding>
</bindings>
以非同步方式呼叫服務
呼叫作業的方式完全取決於用戶端開發人員。 這是因為透過 Managed 程式碼來表達呼叫程序時,您可以將組成作業的訊息對應至同步或非同步的方法。 因此,如果要建置以非同步方式呼叫作業的用戶端,您可以透過 Svcutil.exe,使用 /async
選項來產生非同步用戶端程式碼。 如需詳細資訊,請參閱操作說明:以非同步方式呼叫服務作業。
使用 WCF 用戶端通道呼叫服務
WCF 用戶端會擴充 ClientBase<TChannel>,後者乃衍生自 System.ServiceModel.IClientChannel 介面,以公開基礎通道系統。 您可以搭配 System.ServiceModel.ChannelFactory<TChannel> 類別使用目標服務合約來叫用服務。 如需詳細資料,請參閱 WCF 用戶端架構。