代码之家  ›  专栏  ›  技术社区  ›  Dan Joseph

.NET远程处理异常未处理客户端

  •  2
  • Dan Joseph  · 技术社区  · 15 年前

    我检查了其余的远程处理问题,这个具体的案件似乎没有得到解决。

    我已经设置了.NET远程处理服务器/客户端。在服务器端,我有一个对象,该对象具有一个可以引发异常的方法,以及一个尝试调用该方法的客户机。

    服务器:

    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调用myEquals,该guid导致checkauthentication返回false时,.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
    }
    
    3 回复  |  直到 11 年前
        1
  •  1
  •   Community CDub    8 年前

    首先, do not inherit from ApplicationException . 这个建议已经存在一段时间了,我相信fxcop会自动生成一条关于这个的消息。

    接下来,通常应该用 [Serializable] 属性。我认为这是您的主要问题,因为我在方法调用上得到一个异常,表示authenticationException没有标记为可序列化。

        2
  •  1
  •   to StackOverflow    15 年前

    在客户端尝试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" /> 
        ...
    
        3
  •  0
  •   lilmoe    15 年前

    这个错误有不同的原因,你们提到的不止一对。

    我注意到了这个错误的另一个原因;那就是当远程调用可远程对象的构造函数时抛出和异常。异常没有被序列化,因为对象本身在该点上没有初始化。我相信您应该避免任何可能导致自定义异常被抛出到可远程对象的构造函数中的代码。如果在构造函数内的代码执行过程中引发了系统异常,则应将其作为系统错误(未知)进行处理,并构建一种机制,使用文件系统或其他方法存储该异常的详细信息。

    .NET远程处理在过去听起来确实很有吸引力,但是项目越大,代码中引入的概念越多,该技术显示的弱点就越多。这是一项很好的技术,但您需要大量的经验来从中制定出一个强大的解决方案。