完成本章學習後,您將掌握:
對於熱衷於網路通訊程式設計的開發人員而言,Windows Workflow Foundation (WF) 內建的 Web 服務整合能力極具吸引力。WF 不僅提供了用戶端呼叫 Web 服務的活動,也支援將工作流本身發布為 Web 服務(將於下一章討論)。本章著重於用戶端面向的 InvokeWebServiceActivity,並深入探討其核心屬性、Proxy 設定方式,以及長時間執行服務的 Session 管理機制。
所謂 XML Web 服務,是指基於 SOAP (Simple Object Access Protocol) 協定的服務。SOAP 是一種以 XML 為基礎的通訊框架,其核心思想是將原生資料類型(含複雜結構)序列化為 XML,透過 HTTP 等傳輸協定在網路上交換。早期 SOAP 規格定義了固定的序列化格式,後來隨著 WSDL (Web Services Description Language) 的出現,服務描述更為彈性,允許以訊息導向架構交換任意可序列化的 XML 內容。
當您在 .NET 專案中加入 Web 參考時,Visual Studio 會下載服務的 WSDL,自動產生一個 C# Proxy 類別。這個 Proxy 封裝了網路通訊細節(序列化、SOAP 封裝、HTTP 傳輸),讓您像呼叫本地物件一樣呼叫遠端方法。對呼叫端程式碼而言,除了網路延遲,幾乎感知不到跨機器呼叫的存在。
InvokeWebServiceActivity 是 WF 內建的用戶端 Web 服務呼叫活動,除具備 Proxy 功能外,還支援以單一 Session Cookie 管理多次呼叫。其關鍵屬性如下表:
| 屬性 | 功能說明 |
|---|---|
MethodName | 指定要呼叫的遠端方法名稱。 |
ProxyClass | Proxy 類別的型別名稱;可手動指定,或由 Visual Studio 在拖放活動時自動產生。 |
SessionId | 用於綁定多個 Web 服務呼叫的 Session 識別碼;詳細用法見「Session 管理」一節。 |
Url | Web 服務的端點 URL;實際儲存在專案的 Settings Property Bag 中,亦可透過屬性視窗修改。 |
此外,Invoking 與 Invoked 事件可讓您在呼叫前後攔截 Proxy 物件,進行動態設定(如修改 URL、注入憑證)。
在 Visual Studio 的「加入 Web 參考」對話方塊中,提供四種途徑:

加入參考後,Visual Studio 會自動設定 ProxyClass 與 Url。您只需在屬性視窗的 MethodName 下拉選單中選擇欲呼叫的方法(如 GetQuote),並將方法的參數與回傳值繫結至工作流的相依屬性(如 Symbol、StockValue)。


透過屬性視窗完成 ProxyClass、Url、MethodName 及參數繫結,即為靜態設定。適用於服務端點固定、無需執行期切換憑證的情境。
若需在執行期動態決定 URL、注入認證憑證,或穿透 Proxy 伺服器,可撰寫 Invoking 事件處理常式:
private void InvokeWebServiceActivity_Invoking(object sender, InvokeWebServiceEventArgs e)
{
MyWebServiceProxy proxy = e.WebServiceProxy as MyWebServiceProxy;
if (proxy != null)
{
proxy.Url = "https://new-endpoint.example.com/Service.asmx";
proxy.Credentials = new NetworkCredential("user", "pwd");
// 如需穿透 Proxy 伺服器,可設定 proxy.Proxy 屬性
}
}
HTTP 本質上是無狀態的,每個請求-回應獨立。Web 應用程式透過 Session Cookie 在伺服器端維護狀態(如購物車)。XML Web 服務同樣可啟用 Session,但在 WF 中呼叫時,Cookie 僅存在記憶體中,不會寫入檔案。
人工介入的工作流往往長時間執行。若 Web 服務需長時間處理(如等待訂單履行),客戶端工作流必須定期輪詢狀態。此時必須使用相同的 Session Cookie,否則伺服器無法關聯先前的請求。
第一次呼叫完成時(Invoked 事件)儲存 Cookie:
private void FirstMethod_Invoked(object sender, InvokeWebServiceEventArgs e)
{
MyWebServiceProxy ws = e.WebServiceProxy as MyWebServiceProxy;
foreach (Cookie cookie in ws.CookieContainer.GetCookies(new Uri(ws.Url)))
{
// 持久化 cookie.Name, cookie.Path, cookie.Value, cookie.Domain
SavedCookieName = cookie.Name;
SavedCookiePath = cookie.Path;
SavedCookieValue = cookie.Value;
SavedCookieDomain = cookie.Domain;
}
}
後續呼叫前(Invoking 事件)重建 Cookie:
private void NextMethod_Invoking(object sender, InvokeWebServiceEventArgs e)
{
MyWebServiceProxy ws = e.WebServiceProxy as MyWebServiceProxy;
Cookie cookie = new Cookie
{
Name = SavedCookieName,
Path = SavedCookiePath,
Value = SavedCookieValue,
Domain = SavedCookieDomain
};
ws.CookieContainer.Add(cookie);
}
注意: 若兩個
InvokeWebServiceActivity在同一個工作流執行個體中執行,且共用相同的SessionId,WF 會自動傳遞 Cookie,無需手動管理。手動管理僅在工作流被持久化/卸載後重新載入時必要。
本範例建立一個 QuoteRetrieve 方案,包含主控台宿主應用程式、股票報價 Web 服務、循序工作流庫。工作流呼叫 Web 服務的 GetQuote 方法取得股價並顯示。
QuoteRetrieve 方案,編輯 Workflow1.cs。InvokeWebServiceActivity 至設計介面,Visual Studio 自動彈出「加入 Web 參考」對話方塊。QuoteService → 按「加入參考」。MethodName 為 GetQuote。Symbol 參數繫結至新相依屬性 Symbol,將回傳值繫結至 StockValue。CodeActivity 至其後,命名 ExecuteCode 為 DisplayQuoteValue,撰寫顯示邏輯。


本章詳細介紹了 WF 中呼叫 Web 服務的完整流程:從理解 SOAP/WSDL/Proxy 架構,到使用 InvokeWebServiceActivity 的靜態/動態設定,再到長時間執行服務的 Session Cookie 管理。掌握這些技巧,即可在工作流中可靠地整合外部 Web 服務,支援長時間執行的業務流程。