使用ReceiveAndSendReply活動模闆和WorkflowServiceHost可以很容易地建立一個工作流服務。它可以像一個普通WCF服務一樣與其他應用程式進行通信。大部分的配置也相當簡單。選擇Receive活動并加以配置,和SendReply活動類似。大部分的工作用在設定OperationContract或者ServiceContract上面。
出現了錯誤該怎麼辦
事實上是沒有任何屬性可以用來指定傳回的錯誤。
抛出FaultException
當Workflow服務抛出一個FaultException的時候,非常期待它被及時處理。異常能被當作SOAP錯誤被發送到用戶端,假設用戶端也是.NET,可以将它作為一個FaultException進行捕獲。
抛出FaultException<T>
通常,當您想給異常添加一些額外的資訊,您就需要建立一個額外的類,并用FaultContract屬性聲明服務契約,來指定傳回的錯誤。在用戶端需要添加服務中繼資料,做一個添加服務引用來建立所需的類型。但是,對于工作流服務,沒有用于添加屬性的服務契約類 。就沒有屬性給我們使用來實作這些目的。那麼,我們如何指定與工作流服務互動的異常契約呢?
解決方案
竅門是給工作流上相關的Receive活動添加第二個SendReply。第二個SendReply活動傳回錯誤契約。添加第二個SendReply活動很簡單,隻需右鍵單擊Receive活動,并選擇建立SendReply活動就行了。下一步建立一個變量來儲存的錯誤資訊。

我使用的FaultDetail很簡單,它将所有收到的資料發送回用戶端。
1 using System.Runtime.Serialization;
2 namespace ServicesAndFaults{
3 [DataContract]
4 public class FaultDetail
5 {
6 [DataMember]
7 public int Data { get; set; }
8 }
9 }
10
對于第二個SendReply活動,建立和抛出一個FaultException。工作流流程圖如下所示:
下面的表達式用來初始化錯誤異常
下面的SendReply活動是傳回錯誤,配置如下的:
有了這個設定,可以在用戶端添加Service Reference和使用下面的代碼得到預期的結果
1 static void Main(string[] args)
2 {
3 var proxy = new ServiceClient();
4 try
5 {
6 Console.WriteLine(proxy.GetData(42));
7 }
8 catch (FaultException<FaultDetail> ex)
9 {
10 Console.WriteLine("FaultException<FaultDetail> with {0}", ex.Detail.Data);
11 }
12 catch (FaultException ex)
13 {
14 Console.WriteLine(ex);
15 }
16 Console.ReadLine();
17 }
服務控制台應用程式中工作流輸出如下。請注意,最後一條消息,“the workflow finishing”沒有出現。不要奇怪,我們抛出一個異常其實沒有被捕獲,它終止了工作流。
但想讓工作流繼續跑下去!
有時上面的處理方式很好,但有時候并不是。例如你在一個訂單上工作了1個月了,你會僅僅因為一個異常而終止所有的工作嗎?當然不會。
第二種方法傳回給調用用戶端的個錯誤,隻不過是SendReply活動中自定義的FaultException或FaultException <T>。用戶端不會知道其中的差别,但工作流程還會繼續運作。是以,我需要做的是移出Throw 活動,讓第二個SendReply活動實作它的工作。
這一次,服務控制台應用程式輸出如下:
本文轉自麒麟部落格園部落格,原文連結:http://www.cnblogs.com/zhuqil/archive/2010/03/28/workflow-4-and-soap-faults.html,如需轉載請自行聯系原作者