2009-09-30 79 views
2

我檢查了其餘的遠程處理問題,這個具體的案例似乎沒有解決。.NET遠程處理異常沒有處理客戶端

我有一個.NET Remoting服務器/客戶端設置。在服務器端,我有一個可以拋出異常的方法的對象,以及將嘗試調用該方法的客戶端。

服務器:

public bool MyEquals(Guid myGuid, string a, string b) 
{ 
    if (CheckAuthentication(myGuid)) 
    { 
     logger.Debug("Request for \"" + a + "\".Equals(\"" + b + "\")"); 
     return a.Equals(b); 
    } 
    else 
    { 
     throw new AuthenticationException(UserRegistryService.USER_NOT_REGISTERED_EXCEPTION_TEXT); 
    } 
} 

客戶:

try 
{ 
    bool result = RemotedObject.MyEquals(myGuid, "cat", "dog"); 
} 
catch (Services.Exceptions.AuthenticationException e) 
{ 
    Console.WriteLine("You do not have permission to execute that action"); 
} 

當我打電話使用GUID導致CheckAuthentication返回false MyEquals,.NET試圖拋出異常,並說是的AuthenticationException未處理。這發生在服務器端。這個例外永遠不會被整理到客戶端,我不知道爲什麼。我所看到的所有問題都解決了客戶端處理異常的問題,但它不是自定義異常,而是基本類型。就我而言,我甚至無法將任何例外都通過遠程邊界傳遞給客戶。這是一個AuthenticationException的副本。它位於服務器和客戶端之間的共享庫中。

[Serializable] 
public class AuthenticationException : ApplicationException, ISerializable 
{ 

    public AuthenticationException(string message) 
     : base(message) 
    { 
    } 

    public AuthenticationException(SerializationInfo info, StreamingContext context) 
     : base(info, context) 
    { 
    } 

    #region ISerializable Members 

    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     base.GetObjectData(info, context); 
    } 

    #endregion 
} 

回答

1

首先,do not inherit from ApplicationException。這個建議已經有一段時間了,我相信FxCop會自動產生一個消息。

接下來,您通常應該使用[Serializable]屬性修飾您的自定義例外。我認爲這是你的主要問題,因爲我在方法調用中遇到一個異常,說明AuthenticationException未標記爲可序列化。

+1

啊,是的。這裏是FxCop的消息: 警告:CA1058:Microsoft.Design:更改'AuthenticationException'的基本類型,以便它不再擴展'ApplicationException'。此基本異常類型不爲框架類提供任何附加值。改爲擴展'System.Exception'或一個現有的未密封的異常類型。除非在爲整個異常類創建捕獲處理程序方面有特定的值,否則不要創建新的異常基類型。 – 2009-09-30 17:08:54

+0

啊。對不起。複製我的課程時,我忘了包含該行。我用[Serializable]裝飾我的異常。 – 2009-09-30 17:59:16

+0

我正在閱讀你對Joe的評論,沒有在客戶端捕獲異常。我一起提供了一個快速的Remoting服務器和客戶端工具,它每次都會被客戶端捕獲,而不是在服務器上。我會問一些更多的資格問題,希望能夠指導我們解決這個謎團。 #1:持有MyEquals的類是否來自MarshalByRefObject?如果沒有,應該這樣才能正確地對Remoting進行編組。 #2:你如何託管服務器? IIS,一個Windows服務或只是一個獨立的應用程序來測試? – 2009-09-30 18:57:53

1

在客戶端嘗試catch(Exception),並檢查被捕獲異常的類型以及任何內部異常。它可能會提供一些線索。

其他一些言論:

  • ApplicationException的棄用。你通常應該從System.Exception派生。

  • 我通常會將[Serializable]屬性添加到自定義異常。不知道這是否重要。

  • 您通常應該重寫System.Exception.GetObjectData,而不是顯式實現ISerializable.GetObjectData。在你的情況下,你不會序列化任何額外的數據,所以我不會重寫它,也不明確地實現它。我再次不確定這是否會產生任何影響。

我的模板爲可序列化的自定義異常看起來像下面,我沒有任何問題與遠程連接序列化。

[Serializable] 
public class CustomException : Exception 
{ 

/// <summary> 
/// Initializes a new instance of the <see cref="CustomException"/> class. 
/// </summary> 
public CustomException() 
{ 
} 

/// <summary> 
/// Initializes a new instance of the <see cref="CustomException"/> class with 
/// a specified error message. 
/// </summary> 
public CustomException(string message) : base(message) 
{ 
} 
/// <summary> 
/// Initializes a new instance of the <see cref="CustomException"/> class with 
/// a specified error message and a reference to the inner exception that is a cause 
/// of this exception. 
/// </summary> 
public CustomException(string message, Exception inner) : base(message, inner) 
{ 
} 
/// <summary> 
/// Initializes a new instance of the <see cref="CustomException"/> class with 
/// serialized data. 
/// </summary> 
protected CustomException(SerializationInfo info, StreamingContext context) : base(info, context) 
{ 
} 

} 

UPDATE

此外,如果你正在主持在IIS服務器代碼,你需要在web.config中以下爲允許例外傳播到客戶端:

<system.web> 
    ... 
    <customErrors mode="Off" /> 
    ... 
+0

我爲您的自定義異常模板實現了我的AuthenticationException。客戶端仍然沒有例外。服務器暫停「AuthenticationException未被用戶代碼處理」我是否必須指定服務器應用程序有一個客戶端願意並等待處理所有拋出的異常? – 2009-09-30 18:08:07

+0

「我必須指定給服務器應用程序...」 - 請參閱上面的更新 – Joe 2009-09-30 20:29:19

0

這個錯誤有不同的原因,你們提到的不只是一對夫婦。

我注意到這個錯誤的另一個原因;這就是遠程調用遠程對象的構造函數拋出異常的原因。異常不會被序列化,因爲對象本身在那個時候沒有被初始化。我相信你應該避免任何可能導致自定義異常被拋出遠程對象的構造函數的代碼。並且如果在構造函數內部執行代碼期間拋出了系統異常,則應該將其作爲系統錯誤(未知)處理,並構建一種機制來存儲使用文件系統或其他類型的異常的細節。

.net remoting在日子裏聽起來很吸引人,但是您的項目越大,您向代碼引入的概念越多,此技術顯示出的弱點越多。這是一項很好的技術,但您需要大量經驗才能制定出健全的解決方案。