.NET Remotingexception未处理客户端

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

我有一个.NET Remoting服务器/客户端设置。 在服务器端,我有一个对象,它有一个可以抛出exception的方法,以及一个尝试调用该方法的客户端。

服务器:

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导致CheckAuthentication返回false时,.NET会尝试抛出exception,并说AuthenticationException未处理。 这发生在服务器端。 这个例外永远不会被整理到客户端,我无法弄清楚原因。 我所看到的所有问题都解决了客户端处理exception的问题,但它不是自定义exception,而是基类型。 在我的情况下,我甚至无法通过远程连接到客户端获得任何exception。 这是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 } 

首先, 不要从ApplicationExceptioninheritance 。 这个建议已经存在了一段时间,我相信FxCop会自动生成一个消息。

接下来,您通常应该使用[Serializable]属性修饰自定义exception。 我认为这是你的主要问题,因为我在方法调用上得到一个exception,说AuthenticationException没有标记为可序列化。

在客户端尝试catch(Exception),并检查被捕获的exception的类型以及任何内部exception。 它可能会提供一些线索。

其他一些评论:

  • 不推荐使用ApplicationException。 您通常应该从System.Exception派生。

  • 我通常将[Serializable]属性添加到自定义exception中。 不确定这是否重要。

  • 您通常应该覆盖System.Exception.GetObjectData,而不是显式实现ISerializable.GetObjectData。 在您的情况下,您没有序列化任何其他数据,因此我既不会覆盖它也不会显式实现它。 我不确定这是否会产生任何影响。

我的可序列化自定义exception的模板如下所示,我没有遇到任何通过远程连接进行序列化的问题。

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

UPDATE

此外,如果您在IIS中托管服务器代码,则需要在web.config中使用以下内容以允许exception传播到客户端:

   ...  ... 

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

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

.net remoting在这些日子里听起来真的很吸引人,但是你的项目越大,你引入代码的概念就越多,这项技术所揭示的弱点就越多。 这是一项很好的技术,但是你需要很多经验来制定一个强大的解决方案。