Cook Computing

I noticed this evening when

April 29, 2002 Written by Charles Cook

I noticed this evening when making a SOAP request to a XML-RPC.NET Remoting server that if the server throws an instance of XmlRpcFaultException (which in the XML-RPC case would be automatically mapped onto a Fault Response) the exception object was not returned to the client - because it could not be serialized. At first I naively assumed that marking the XmlRpcFaultException class with the Serializable attribute would be sufficient. But there is more to it than this.

The problem is that XmlRpcFaultException has System.Exception as one of its base classes and System.Exception derives from ISerializable. If a base class derives from this interface, derived classes also have to implement the ISerializable interface rather than rely on the default serialization provided by the Serializable attribute (though this attribute is still required). Two methods must be implemented: GetObjectData to serialize the object with the data required to persist its state and a deserialization constructor to rehydrate the object from the serialized state. Note that both these methods must invoke the corresponding method on the immediate base class.

The relevant parts of XmlRpcFaultException now look like this:


[Serializable]
public class XmlRpcFaultException : ApplicationException
{
  // deserialization constructor
  protected XmlRpcFaultException(SerializationInfo info, 
    StreamingContext context) 
    : base(info, context) 
  {
    m_faultCode = (int)info.GetValue("m_faultCode", typeof(int));
    m_faultString = (String)info.GetValue("m_faultString", 
      typeof(string));
  }
  // .... 
  public override
  void GetObjectData(SerializationInfo info, 
    StreamingContext context)
  {
    info.AddValue("m_faultCode", m_faultCode);
    info.AddValue("m_faultString", m_faultString);
    base.GetObjectData(info, context);
  }
  int m_faultCode;
  string m_faultString;
}