.NET Remoting exception is not handled client side

I checked the rest of the remote access questions and this particular case didn't seem to be addressed.

I have a .NET Remoting server / client configured. On the server side, I have an object with a method that can throw an exception, and a client that 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);
    }
}

      

Customer:

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 an instruction that returns CheckAuthentication to return false, .NET tries to throw an exception and says that the authentication exception was unhandled. This happens on the server side. The exception is never translated to the client side and I can't figure out why. All of the questions I have looked at are about client-side exception handling, but this is not a normal exception, but a basic type. In my case, I can't even get exceptions to cross the border of remote client access. Here is a copy of the AuthenticationException. It resides in a shared library between 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
}

      

+2


source to share


3 answers


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



Then you should usually decorate your custom exception with an attribute [Serializable]

. I think this is your main problem as I am getting an exception in the method call saying the AuthenticationException is not marked serializable.

+1


source


Try to catch (exception) on the client side and check the type of the caught exception as well as any internal exceptions. This may provide some clues.

Some other notes:

  • ApplicationException is deprecated. Usually you should be pulling from System.Exception.

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

  • Usually, you should override System.Exception.GetObjectData and not explicitly use ISerializable.GetObjectData. In your case, you are not serializing any additional data, so I would not override it and implement it explicitly. Again, I'm not sure if this will affect.

My template for a serializable custom exception looks like this and I had no problem serializing over a remote 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 are hosting server code in IIS, you need the following in your web.config to allow exception propagation to the client:

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

      

+1


source


There are various reasons for this error and you guys mentioned more than a couple.

I noticed another reason for this error; and that when the constructor of a remote object is called remotely throws and excludes. exceptions are not serialized because the object itself was not initialized at that point. I believe that you should avoid ANY code that could cause a custom exception to be thrown inside the constructor of remote objects. and if a system exception was thrown during code execution inside the constructor, you have to deal with it as a system error (unknown) and create a mechanism to store information about this exception using the file system or whatever.

.net remoting sounded very appealing in those days, but the larger your project, the more concepts you introduce into your code, the more the technology's flaws will reveal. this is good technology, but you need a lot of experience to come up with a reliable solution.

0


source







All Articles