2009-09-30 82 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在日子里听起来很吸引人,但是您的项目越大,您向代码引入的概念越多,此技术显示出的弱点越多。这是一项很好的技术,但您需要大量经验才能制定出健全的解决方案。