Wcf异常 FaultException


FaultException defined on OperationContract throw new Exception() throw new FaultException<T>
[ServiceBehavior(IncludeExceptionDetailInFaults=true)]
 
[FaultContract(typeof(Exception))]        
N Y N N "The server was unable to process the request due to an internal error.
N N Y N "The creator of this fault did not specify a Reason."
Y Y N N "The server was unable to process the request due to an internal error.
Y N Y N FaultException<T> gets server response, Reason is a message, Detail is InnerException,which is instance of T.

1. IncludeExceptionDetailInFaults 可以做到: 牺牲性能和安全, 把异常发送到client以供调试.

2. 当在服务端抛出一个Exception, 例如InvalidOperationException的时候, 服务端其实已经崩溃了, Wcf架构截获了这个异常并通知client, 没有任何有效消息, 除非

[ServiceBehavior(IncludeExceptionDetailInFaults=true)]设置为true

3. 服务端抛出一个FaultException<T> 的时候, 可以认为服务端是"假崩溃", 只是把T exception 封送到客户端, 然后关闭服务端. (取决于实例类型,single的话,实例没有被销毁掉), 但是client可能不知道具体异常而转为CommunicationException。

4. 没有为OperationContract指定FaultException 的时候, wcf不知道给client封送什么样的数据. 所以client 还是不知道服务端错误是什么. 考虑到wcf其实在这个包装阶段, 其实已经把service 实例转化为一个接口, 如果接口没有一个Customized attribute, 即服务端不知道Exception如何序列化. 过程可能类似,

IContract c = svcClassInstance as IContract;

Type t = c.GetType().GetCustomAttributes(true)[0].GetType();

c.FunCall();

Catch(Exception e) //这里就可以知道e到底是什么类型的东西了

5. OperationContract 有指定FaultException 类型, 服务端抛出FaultException<T>, client 运行catch FaultException<T>, 运行正常

 

Best practice:

1 在定义interface的时候, 如果一个函数需要抛出异常, 必须为操作设定异常类型,以便让WCF framework在通知客户端的时候知道是什么异常并如何封送

[ServiceContract] 

interface IContract {

[OperationContract]

[FaultContract(typeof(UserDefineException))]

void FunctionCall();

}

2. 永远只在service 的类方法里, 抛出FaultException<T>, 在reason里填写服务器信息, 而不是Exception, 前提必须client端有定义FaultContract

也就是说, 在服务端方法里catch一次, 然后只抛出一个异常. 客户端只需要结果, 具体异常类型在Detail可以看到

3. client类方法里面, 需要catch的至少要有

FaultException<T>, 一般来说, Reason用来给界面提示, Detail用来调试; 因为reason可以有多语言支持的一个translate实现, Detail则不太好弄

FaultException, 用来截获服务端的未定义异常(因为不能保证service是自己写的, 或者运行没有其他异常)

CommunicationException, 虽然可以判断State是否open, 但是其他连接性问题不可忽视

Exception, client的本地异常, 及其他

4. IncludeExceptionDetailInFaults = true 最好只写在配置文件里, 这样发布release版本的时候则可以容易修改。 这个只用来调试, 在任何发布版本都不应该使用

posted on 2010-05-09 22:46  无法显示此网页  阅读(1559)  评论(0编辑  收藏  举报

导航