I was looking at Jason Jackson's answer, but it didn't make sense to me that I'm having problems with this even though System.Exception implements ISerializable. So I bypass the XmlSerializer by wrapping the exception in a class that uses a BinaryFormatter instead. When the XmlSerialization of the MS Message Queuing objects kicks in all it will see is a class with a public byte array.
Here's what I came up with:
public class WrappedException
{
public byte[] Data;
public WrappedException()
{
}
public WrappedException(Exception e)
{
SetException(e);
}
public Exception GetException()
{
Exception result;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream stream = new MemoryStream(Data);
result = (Exception)bf.Deserialize(stream);
stream.Close();
return result;
}
public void SetException(Exception e)
{
MemoryStream stream = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(stream, e);
Data = stream.ToArray();
stream.Close();
}
}
The first test worked perfectly, but I was still concerned about custom exceptions. So I tossed together my own custom exception. Then I just dropped a button on a blank form. Here's the code:
[Serializable]
public class MyException : Exception, ISerializable
{
public int ErrorCode = 10;
public MyException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
ErrorCode = info.GetInt32("ErrorCode");
}
public MyException(string message)
: base(message)
{
}
#region ISerializable Members
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue("ErrorCode", ErrorCode);
}
#endregion
}
private void button1_Click(object sender, EventArgs e)
{
MyException ex = new MyException("Hello, world!");
ex.ErrorCode = 20;
WrappedException reply = new WrappedException(ex);
XmlSerializer x = new XmlSerializer(reply.GetType());
MemoryStream stream = new MemoryStream();
x.Serialize(stream, reply);
stream.Position = 0;
WrappedException reply2 = (WrappedException)x.Deserialize(stream);
MyException ex2 = (MyException)reply2.GetException();
stream.Close();
Text = ex2.ErrorCode.ToString(); // form shows 20
// throw ex2;
}
Although it seemed like all of other exception types that I looked up are marked with the SerializableAttribute, I'm going to have to be careful about custom exceptions that are not marked with the SerializableAttribute.
EDIT: Getting ahead of myself. I didn't realize that BinaryFormatter is not implemented on CF.
EDIT: Above code snippets were in a desktop project. In the CF version, the WrappedException will basically look the same I just need to implement my own BinaryFormater, but I'm very open to suggestions on that one.