2012-07-18 46 views
1

這是我觀察到的如何通過WCF將自定義異常的字段傳播到客戶端?

我需要從客戶端向服務拋出一個自定義的Exception子類型。 (在特定操作中列爲FaultContract)。我有CustomException的某些字段,應該由客戶端接收。

}

我發現場沒有被反序列化,即使例外是目前的FaultException實例中。我嘗試通過重寫GetObjectData和序列化ctor來實現ISerializable,但沒有骰子。 我能得到它的唯一方法是將MyCustomException更改爲DataContract,而不是從Exception派生。

[DataContract] 
class MyCustomException 
{ 
    [DataMember] 
    public string From { get; private set; } 

    public MyCustomException(string where) 
    { 
     From = where; 
    } 
} 

這是有效的。然而,它不能從異常中派生出來。因爲異常是用Serializable屬性標記的,並且你不能同時擁有一個類型的Serializable和DataContract。 (確認:運行時拋出異常)

所以我的問題是:在WCF中傳播自定義異常子類型的字段的正確方法是什麼?

回答

2

...你不能同時擁有一個類型的Serializable和DataContract。 (確認:拋出運行時異常)

首先,你可以有DataContractSerializable在一起。事實上,沒有這個,我現在正在處理的網站將無法工作,因爲我的WCF服務通過$.ajax通過網絡消耗。 This SO線程將爲您提供正式的詳細信息。

接下來,我強​​烈建議不要從Exception繼承您的自定義錯誤。原因是你已經有一個FaultException<TDetail>內置類,其中TDetail是你的自定義錯誤。您可以閱讀this MSDN文章以瞭解實施細節 - 請記住在部署期間在客戶端關閉「異常詳細信息」。

catch (FaultException<MyFault> e) 
{ 
    //e is the full exception (with StackTrace et al.) when 'exception details' is on 
    //e.Detail is your custom fault which is always available 
} 
+1

此鏈接具有我使用DataContractAttribute標記異常子類型時看到的確切錯誤消息。 http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/5fdfc1d7-89f2-4f8b-a491-d9ac2cb0600c/看起來WCF應該支持ISerializable模型,那麼爲什麼不MyCustomException什麼時候用SerializableAttribute標記工作? – Gishu 2012-07-19 07:20:34

+0

找到了我的問題的答案 - 由於基類型的異常實現ISerializable ..派生類型也必須遵守和覆蓋序列化其特定的字段。 – Gishu 2012-07-19 10:10:18

1

下面是我如何得到它的工作..不知道它是否是正確的方式。 我找不到任何明確的指導說明,您不應該使用Exception子類型作爲FaultException<TDetail>中的TDetail參數。

我試着扔了一個FaultException<FileNotFoundException>,發現文件名字段實際上是正確傳播的。

那麼FileNotFoundException和MyCustomException之間的增量是多少?

由於基座例外實現ISerializable的,我在服務器端不得不覆蓋的方法 ..

protected MyCustomException(SerializationInfo info, StreamingContext context) : 
     base(info, context) 
    { 
     this.From = info.GetString("From"); 
    } 
    public override void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     base.GetObjectData(info, context); 
     info.AddValue("From", this.From); 
    } 

我然後用於SvcUtil工具生成客戶端代理類。我發現沒有生成FileNotFoundException(因爲它是一個內置類型),但MyCustomException是。但它沒有任何字段,只有一個空的反序列化ctor。

我沒有深入到早期的ISerializable,因爲當我在代理類ctor中設置斷點時,它沒有被擊中。我錯誤地中止了調查的這一行(無法看到類的DebuggerStepThrough屬性和GeneratedCode屬性;由svcutil添加)。

所以我當時手動編輯自動生成的類添加字段並設置它在像這樣的構造函數..

[System.SerializableAttribute()] 
    public partial class MyCustomException : System.Exception 
    { 
     public string From { get; private set; } // manual edit 

     public MyCustomException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : 
      base(info, context) 
     { 
      this.From = info.GetString("From"); // manual edit 
     } 
    } 

現在它按預期工作;現場數據完好無損。

這引發了另一個問題:爲什麼代理生成步驟不會自動執行此操作?

相關問題