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

发布于 2024-08-06 10:03:57 字数 1511 浏览 8 评论 0原文

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

我设置了 .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 调用 MyEquals 时,导致 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
}

I checked the rest of the remoting questions, and this specific case did not seem to be addressed.

I have a .NET Remoting server/client set up. On the server side I have an object with a method that can throw an exception, and a client which will try to call that method.

Server:

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);
    }
}

Client:

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

When I call MyEquals with a Guid which causes CheckAuthentication to return false, .NET tries to throw the exception and says the AuthenticationException was unhandled. This happens server side. The exception is never marshaled over to the client-side, and I cannot figure out why. All of the questions I have looked at address the issue of an exception being handled client-side, but it isn't the custom exception but a base type. In my case, I can't even get any exception to cross the remoting boundary to the client. Here is a copy of AuthenticationException. It is in the shared library between both server and client.

[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
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

意中人 2024-08-13 10:03:57

首先也是最重要的, 不要继承 ApplicationException< /a>.这个建议已经存在了一段时间,我相信 FxCop 会自动生成一条关于此的消息。

接下来,您通常应该使用 [Serialized] 属性来装饰自定义异常。我认为这是您的主要问题,因为我在方法调用上遇到异常,说 AuthenticationException 未标记为可序列化。

First and foremost, do not inherit from ApplicationException. This advice has been around for a while, and I believe FxCop will automatically generate a message around this.

Next, you should usually decorate your custom exception with the [Serializable] attribute. I think this is your main issue, as I get an exception on the method call saying AuthenticationException is not marked as serializable.

白色秋天 2024-08-13 10:03:57

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

其他一些注释:

  • ApplicationException 已弃用。通常应该从 System.Exception 派生。

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

  • 您通常应该重写 System.Exception.GetObjectData,而不是显式实现 ISerialized.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" /> 
    ...

Try catch(Exception) on the client side, and inspect the type of the exception being caught as well as any inner exceptions. It might give some clues.

Some other remarks:

  • ApplicationException is deprecated. You should normally derive from System.Exception.

  • I normally add the [Serializable] attribute to custom exceptions. Not sure if this is important.

  • You should normally override System.Exception.GetObjectData rather than explicitly implementing ISerializable.GetObjectData. In your case you're not serializing any additional data, so I would neither override it nor explicitly implement it. Again I'm unsure if this would have any impact.

My template for a serializable custom exception looks like the following, and I haven't had any problems with serialization over a remoting connection.

[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

Also if you're hosting the server code in IIS, you need the following in web.config to allow exceptions to propagate to the client:

  <system.web>
    ...
    <customErrors mode="Off" /> 
    ...
酒绊 2024-08-13 10:03:57

导致此错误的原因有多种,你们已经提到了不止几个。

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

.net 远程处理在过去听起来确实很有吸引力,但是您的项目越大,向代码引入的概念越多,该技术暴露的弱点就越多。这是一项很好的技术,但您需要大量的经验才能利用它制定强大的解决方案。

There are different reasons for this error, and you guys have mentioned more than a couple.

I have noticed another reason for this error; and that's when the constructor of the remotable object being called remotely throws and exception. the exceptions are not being serialized because the object itself wasn't initialized at that point. i believe you should avoid ANY code that might cause a custom exception to be thrown inside the remotable object's constructor. and if a system exception was thrown during the execution of the code inside the constructor, you should deal with it as a system error (unknown) and build a mechanism to store the details of that exception using the file system or whatever.

.net remoting sounded really appealing back in the days, but the larger your project gets, and the more concepts you introduce to your code, the more weaknesses this technology reveals. it's a good technology, but you need lots of experience to make a robust solution out of it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文