很多规范中都提到,自定义Exception 要求使用一种统一的构造函数,比如默认实现以下四个构造函数。
public class XXXException:ApplicationException
{
public XXXException():base()
{
}
public XXXException(string message):base(message)
{
}
public XXXException(string message,Exception innerException):base(message,innerException)
{
}
protected XXXException ( System.Runtime.Serialization.SerializationInfo info , System.Runtime.Serialization.StreamingContext context ):base(info,context)
{
}
}
这样做有几个好处
1. 前三个构造函数可以提供一直的实现方式
2. 最后一个构造函数是对象使用 soap 或者binary formattor 反序列化的时候比不可少的构造函数。否则你的remoting 对象服务端抛出的异常,无法bubble 到客户端。
我写一个简单的soap formattor 的例子来模拟remoting 对象的传递
XXXException ex = new XXXException( " invalid. " );
FileStream fs = new FileStream( " soap.xml " ,FileMode.Create );
System.Runtime.Serialization.Formatters.Soap.SoapFormatter sr = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
sr.Serialize(fs,ex);
fs.Flush();
fs.Close();
// TODO 2 soap 翻序列化
XXXException exp;
FileStream fs1 = new FileStream( " soap.xml " ,FileMode.Open);
System.Runtime.Serialization.Formatters.Soap.SoapFormatter dsr = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
exp = (XXXException)dsr.Deserialize(fs1);
fs1.Close();
MessageBox.Show(exp.Message);
如果没有xxxexception 的第四个构造函数,可能会有
An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll
Additional information: The constructor to deserialize an object of type ExceptionDemo.XXXException was not found.
当然这个是针对 remoting,web service 走得是 xml serilizer,目前这个版本对 属性中有申明权限要求的字段无法序列化。所以web service 中,你是无法直接讲 exception 传递给客户端。
比如一下例子
[WebMethod]
public string HelloWorld(string s,out Exception ex)
{
ex=new FormatException("fasdf");
return "Hello World";
}
你会发现这个例子无法在客户端调用,呵呵。