WCF 用戶端概觀
本節描述用戶端應用程式的功能、Windows Communication Foundation (WCF) 用戶端的設定、建立和使用方式,以及保護用戶端應用程式安全的方法。
使用 WCF 用戶端物件
用戶端應用程式是使用 WCF 用戶端與其他應用程式進行通訊的一種 Managed 應用程式。建立 WCF 服務的用戶端應用程式時,需要執行下列步驟:
取得服務端點的服務合約、繫結和位址資訊。
使用這些資訊建立 WCF 用戶端。
呼叫作業。
關閉 WCF 用戶端物件。
下列各節將討論這些步驟,並簡要介紹以下問題:
處理錯誤。
設定和保護用戶端。
建立雙工服務的回呼物件。
非同步呼叫服務。
透過用戶端通道呼叫服務。
取得服務合約、繫結和位址
在 WCF 中,服務和用戶端模型合約會使用 Managed 屬性、介面和方法。若要在用戶端應用程式中連接到服務,您必須取得服務合約的類型資訊。一般而言,要取得這項資訊,可以使用 ServiceModel 中繼資料公用程式工具 (Svcutil.exe),此工具會從服務下載中繼資料,然後將它轉換為您所選擇語言的 Managed 原始程式碼檔,再建立可用來設定 WCF 用戶端物件的用戶端應用程式組態檔。例如,如果您要建立 WCF 用戶端物件來叫用 MyCalculatorService
,並且知道這個服務的中繼資料的發行位置是在 http://computerName/MyCalculatorService/Service.svc?wsdl
,那麼下列程式碼範例將會告訴您如何使用 Svcutil.exe 來取得 ClientCode.vb
檔案,該檔案包含以 Managed 程式碼撰寫的服務合約。
svcutil /language:vb /out:ClientCode.vb /config:app.config http://computerName/MyCalculatorService/Service.svc?wsdl
您可以將這段合約程式碼編譯成用戶端應用程式,或編譯成用戶端應用程式能用來建立 WCF 用戶端物件的另一個組件。您可以使用組態檔來設定用戶端物件,以便正確連接到服務。
如需這個程序的範例,請參閱 HOW TO:建立 Windows Communication Foundation 用戶端。如需合約的詳細資訊,請參閱合約。
建立 WCF 用戶端物件
WCF 用戶端為本機物件,這個物件是以用戶端可用於和遠端服務通訊的形式來表示 WCF 服務。WCF 用戶端型別會實作目標服務合約,所以當您建立並設定服務合約時,就可以直接使用用戶端物件來叫用服務作業。WCF 執行階段會將方法呼叫轉換為訊息並傳送至服務,然後接聽回覆,再將這些值當做傳回值或 out 或 ref 參數傳回給 WCF 用戶端物件。
您也可以使用 WCF 用戶端通道物件來連接及使用服務。如需詳細資訊,請參閱用戶端架構。
建立新的 WCF 物件
為說明 ClientBase 類別的使用方式,請假設已從服務應用程式產生下列簡單服務合約。
注意: |
---|
如果您使用 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 和服務合約介面 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),因為這可能會對特定失敗模式的例外狀況做遮罩處理。如需詳細資訊,請參閱下列各節以及避免 Using 陳述式發生問題。
合約、繫結和位址
您必須先設定用戶端物件,才可以建立 WCF 用戶端物件。具體來說,就是必須有要使用的服務「端點」(Endpoint)。端點是服務合約、繫結和位址的組合 (如需詳細資訊端點的詳細資訊,請參閱端點:位址、繫結和合約)。一般而言,這項資訊位於用戶端應用程式組態檔 (例如,Svcutil.exe 工具產生的組態檔) 中的 <endpoint> 項目,並且會在您建立用戶端物件時自動載入。這兩個 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="https://localhost:8080/SampleService" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ISampleService" contract="ISampleService"
name="WSHttpBinding_ISampleService">
</endpoint>
</client>
</system.serviceModel>
</configuration>
這個組態檔會在 <client>
項目中指定目標端點。如需詳細資訊使用多個目標端點的詳細資訊,請參閱 System.ServiceModel.ClientBase.#ctor(System.String) 或 System.ServiceModel.ChannelFactory.#ctor(System.String) 建構函式。
呼叫作業
建立並設定用戶端物件之後,請建立 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 區塊中進行。如需詳細資訊,請參閱使用用戶端存取服務和避免 Using 陳述式發生問題。
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.ServiceModel.FaultException 物件之外,建議您最少還要讓應用程式有能力處理可能發生的 System.TimeoutException 和 System.ServiceModel.CommunicationException 例外狀況。作業合約中指定的 SOAP 錯誤會針對用戶端應用程式引發為 System.ServiceModel.FaultException,其中的型別參數是 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 類別來指定用戶端基底位址,否則會擲回例外狀況。下列程式碼範例示範如何在程式碼中執行這項工作。
Dim dualBinding As New WSDualHttpBinding()
Dim endptadr As New EndpointAddress("https://localhost:12000/DuplexTestUsingCode/Server")
dualBinding.ClientBaseAddress = New Uri("https://localhost:8000/DuplexTestUsingCode/Client/")
WSDualHttpBinding dualBinding = new WSDualHttpBinding();
EndpointAddress endptadr = new EndpointAddress("https://localhost:12000/DuplexTestUsingCode/Server");
dualBinding.ClientBaseAddress = new Uri("https://localhost:8000/DuplexTestUsingCode/Client/");
下列程式碼範例示範如何在組態檔中執行這項工作。
' <client>
' <endpoint
' name ="ServerEndpoint"
' address="https://localhost:12000/DuplexUsingConfig/Server"
' bindingConfiguration="WSDualHttpBinding_IDuplex"
' binding="wsDualHttpBinding"
' contract="IDuplex"
' />
' </client>
' <bindings>
' <wsDualHttpBinding>
' <binding
' name="WSDualHttpBinding_IDuplex"
' clientBaseAddress="https://localhost:8000/myClient/"
' />
' </wsDualHttpBinding>
' </bindings>
<client>
<endpoint
name ="ServerEndpoint"
address="https://localhost:12000/DuplexUsingConfig/Server"
bindingConfiguration="WSDualHttpBinding_IDuplex"
binding="wsDualHttpBinding"
contract="IDuplex"
/>
</client>
<bindings>
<wsDualHttpBinding>
<binding
name="WSDualHttpBinding_IDuplex"
clientBaseAddress="https://localhost:8000/myClient/"
/>
</wsDualHttpBinding>
</bindings>
以非同步方式呼叫服務
呼叫作業的方式完全取決於用戶端開發人員。這是因為透過 Managed 程式碼來表達呼叫程序時,您可以將組成作業的訊息對應至同步或非同步的方法。因此,如果要建置以非同步方式呼叫作業的用戶端,您可以透過 Svcutil.exe,使用 /async 選項來產生非同步用戶端程式碼。如需詳細資訊,請參閱 HOW TO:以非同步方式呼叫 WCF 服務作業.
使用 WCF 用戶端通道呼叫服務
WCF 用戶端型別會擴充 ClientBase,而後者則是從 System.ServiceModel.IClientChannel 介面衍生以公開基礎通道系統。您可以搭配 System.ServiceModel.ChannelFactory 類別使用目標服務合約來叫用服務。如需詳細資訊,請參閱用戶端架構。
另請參閱
參考
System.ServiceModel.ClientBase
System.ServiceModel.ChannelFactory