我正在查看 Jason Jackson 的答案,但即使 System.Exception 实现了 ISerializable,我也没有任何意义。因此,我通过将异常包装在使用 BinaryFormatter 的类中来绕过 XmlSerializer。当 MS 消息队列对象的 XmlSerialization 启动时,它将看到一个具有公共字节数组的类。
这是我想出的:
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();
}
}
第一个测试运行良好,但我仍然担心自定义异常。所以我把我自己的自定义异常扔在一起。然后我只是在一个空白表格上放了一个按钮。代码如下:
[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;
}
虽然我查找的所有其他异常类型似乎都标有 SerializableAttribute,但我必须小心未标有 SerializableAttribute 的自定义异常。
编辑:超越自己。我没有意识到 BinaryFormatter 没有在 CF 上实现。
编辑:上面的代码 sn-ps 在桌面项目中。在 CF 版本中,WrappedException 基本上看起来与我只是需要实现我自己的 BinaryFormater 相同,但我非常愿意接受关于那个的建议。