簡體   English   中英

客戶端未處理.NET Remoting異常

[英].NET Remoting Exception not handled Client-Side

我檢查了其余的遠程處理問題,但似乎未解決此特定情況。

我已經設置了.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");
}

當我使用導致CheckAuthentication返回false的Guid調用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
}

在客戶端嘗試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)
{
}

}

更新

另外,如果要在IIS中托管服務器代碼,則需要在web.config中執行以下操作,以允許異常傳播到客戶端:

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

首先, 不要從ApplicationException繼承 該建議已經存在了一段時間,我相信FxCop會自動圍繞此生成消息。

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

出現此錯誤的原因多種多樣,你們提到的不只幾個。

我注意到此錯誤的另一個原因; 這就是遠程調用遠程對象的構造函數時拋出的異常。 異常沒有被序列化,因為此時對象本身尚未初始化。 我相信您應該避免任何可能導致自定義異常拋出於可遠程對象的構造函數中的代碼。 並且如果在構造函數內部執行代碼期間拋出系統異常,則應將其視為系統錯誤(未知),並建立一種機制來使用文件系統或任何其他方式存儲該異常的詳細信息。

過去,.net遠程聽起來確實很吸引人,但是您的項目獲得的規模越大,您在代碼中引入的概念越多,該技術所揭示的缺點就越多。 這是一項很好的技術,但是您需要大量經驗才能制定出可靠的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM