第6章错误
不管是哪一种服务操作,在任意时刻都可能遭遇一些不可预期的错误。问题在于如何将错误报告给客户端。异常与异常处理机制是与特定的技术紧密结合的,不能够跨越服务边界。此外,错误处理通常都属于本地的实现细节,不会影响到客户端。这样设计的原因在于客户端不需要关心错误的细节(以及发生错误的事实),但最主要的还是因为在设计良好的应用程序中,服务是被封装的,因此客户端无法知道有关错误的信息。设计良好的服务应尽可能是自治的,不能依赖于客户端去处理或恢复错误。任何非空的错误通知都应该是客户端与服务之间契约交互的一部份。本章介绍了服务与客户端如何处理这些声明的错误,以及如何扩展与改善这样一种基础的实现机制。
错误与异常
在传统的.NET编程中,任何未经处理的异常都会立刻终止抛出异常的进程。但WCF却与之大相径庭。如果代表某个客户端的服务调用导致异常,并不会结束宿主进程,其他客户端仍然可以访问该服务,托管在相同进程中的其他服务也不会受到影响。因此,当一个未经处理的异常离开服务的范围时,分发器会捕获它,并将它序列化到返回消息中传递给客户端。当返回消息到达代理时,代理会在客户端抛出一个异常。
当客户端试图调用服务时,实际上可能会遭遇三种错误类型。第一种错误类型为通信错误,例如网络故障、地址错误、宿主进程没有运行等。客户端的通信错误表现为CommunicationException异常。
客户端可能遇到的第二种错误类型与代理和通道的状态有关,例如试图访问已经关闭的代理,就会导致ObjectDisposedException异常。或者契约与绑定的安全保护级别不相匹配,也会出现错误。
第三种错误类型源于服务调用。这种错误既可能是服务抛出的异常,也可能是服务在调用其他对象或资源时,通过内部调用抛出的异常。这些错误正是本章所要讲述的主题。
出于封装与解耦的目的,在默认情况下,所有服务端抛出的异常总是以FaultException类型到达客户端:
public class FaultException : CommunicationException |
异常与实例管理
当服务实例出现异常时,WCF并不会关闭宿主进程,但错误可能会影响服务实例,同时还会影响到客户端继续使用代理(事实上是通道)访问服务的能力。准确的说,异常对于客户端与服务实例的影响与服务的实例模式有关。
单调服务与异常
如果调用引发异常,那么紧跟在异常之后,服务实例会被释放,代理将在客户端抛出FaultException异常。在默认情况下,所有服务抛出的异常(包括FaultException的派生类)会使得通道发生错误。即使客户端捕获了异常,它也不能发出随后的调用,因为它们会引发一个CommunicationObjectFaultedException异常。此时,客户端只能关闭代理。
会话服务与异常
无论使用何种WCF会话绑定,在默认情况下,所有异常(包括FaultException的派生类)都会终止会话。WCF将会释放实例,而客户端则获得一个FaultException异常。即使客户端捕获了该异常,也不能继续使用代理,因为随后的调用会引发一个CommunicationObjectFaultedException异常。客户端唯一可以安全执行的就是关闭代理,因为一旦参与会话的服务实例遇到了错误,会话就不能再使用了。
单例服务与异常
当我们调用单例服务时,如果遇到异常,单例实例并不会终止,而是继续运行。在默认情况下,所有异常(包括FaultException的派生类)都会导致通道发生错误,客户端无法发出随后的调用,只能关闭代理。如果客户端包含了一个单例实例的会话,那么会话会终止。
错误
异常的根本问题在于它们与特定的技术紧密结合,因此无法跨越服务边界被调用两端共享。若要考虑良好的互操作性,我们就需要将基于特定技术的异常映射为某种与平台无关的错误信息。这种表现形式就是所谓的SOAP错误(SOAP Fault)。SOAP错误基于一种行业标准,它不依赖于任何一种诸如CLR异常、Java异常或C++异常之类的特定技术的异常。若要为了抛出一个SOAP错误(或者简称错误),服务就不能抛出一个传统的CLR异常,而是抛出一个FaultException
例6-1:FaultException
[Serializable] //更多特性 |
FaultException
FaultException
例6-2演示了一个简单的计算器服务,在实现Divide()方法时,如果除数为0,则抛出一个FaultException
例6-2:抛出FaultException
[ServiceContract] |
除了FaultException
throw new FaultException
但是,将Exception派生类作为错误细节类型更加符合传统的.NET编程实践,代码也具有更强的可读性。此外,它允许实现后面将要讨论的异常提升(Exception Promotion)功能。
传递给FaultException
DivideByZeroException exception = new DivideByZeroException(); |
| 回书目 上一节 |
|
· C语言之基础自测获奖名.. · Linux服务器架设自测获.. · 边界网关安全防护自测.. · Cisco CCNA最新真题自.. · 我在美联储监管银行 书.. · 我在美联储监管银行 目.. |
· 我在美联储监管银行 前.. · 入侵的艺术 目录 · 入侵的艺术 前言 · 网管员全真面试题自测.. · 子弹的本质—— 形势没.. · 学习大量的词汇—— 对.. |
|
||||
| · 华为、贝恩资本22亿美.. · 中间件应用技术专题 · 杀毒软件优化和使用技巧 · 信息安全等级保护专题 · 补丁自动分发管理策略.. · 杀毒王牌 · AMD Phenom三核处理器.. · 国际文档格式标准开战 |
· 51CTO主编推荐经典专题 · 假期读书充电 · 2007盘点专题:有多少.. · 主流品牌防火墙配置 · Linux防火墙 · 了解统一威胁管理(UTM).. · 入侵防护系统(IPS)初探 · 如何优化IT 控制能耗 |
|||
|
||||
| · VPN技术 · SQL Server 2005全解 · SOA 面向服务架构 · 子网掩码教程 · SQL Server 2005全解 · 中间件应用技术专题 · 三层交换技术专题 · Windows远程桌面应用 |
· 深入了解PGP加密技术 · MySQL数据库备份 · 病毒查杀专题 · VPN技术 · Solaris 10 配置管理 · Linux 基础 · SSL VPN详细知识 · Linux防火墙 |
|||
|
||||
| · VPN技术 · SQL Server 2005全解 · 中间件应用技术专题 · SQL Server 2005全解 · SOA 面向服务架构 · 子网掩码教程 · 三层交换技术专题 · Windows远程桌面应用 |
· MySQL数据库备份 · 身份认证技术 · 病毒查杀专题 · 清除流氓软件——51CTO.. · SSL VPN详细知识 · Sniffer安全技术从入门.. · 常用交换机典型配置 · 路由器设置与口令恢复 |
|||