WCF入门(七)——异常处理1
首先以一个简单的例子演示一下远程调用发生异常的结果:
服务器端代码如下:
[ServiceContract]
public interface IService1
{
[OperationContract]
void ErrorTest();
}
public class Service1 : IService1
{
public void ErrorTest() { throw new InvalidOperationException("异常测试");
}
该服务非常简单,直接抛一个异常。当运行客户端代码触发这个异常时,客户端会接收到如下异常:
从中我们可以看到:虽然服务器端抛出的是InvalidOperationException异常,但是客户端接收到的却是FaultException异常。从WCF测试客户端的传递的消息中也可以看出这一点。
WCF异常处理机制
- 通讯异常,这通常是因为链路的原因,比如服务没有启动,网络阻塞等。通常是CommunicationException或者其派生类
- 超时异常,这类异常是因为操作时间超时,超时时会抛出 TimeoutException。
- 服务异常,由服务端根据具体的业务逻辑触发,当业务逻辑抛出异常时,会将其封装成FaultException抛给客户端。
通信异常和超时异常是由WCF框架所产生的,由于网络原因,它们出现是正常的,因此也被称为预期异常,是正常调用的时候需要处理的异常。而FaultException异常则是业务逻辑中异常情况时出现的异常,是由自己实现的代码中产生的,是非预期的异常。具体处理方式根据业务逻辑而定。
但值得注意的是:服务被设置为PerSession模式或者Single模式,服务异常还会导致服务对象被释放而终止服务。(这个是在网上看到的说明,但我自己试的时候没有挂,从WCF服务对象模型上来分析也不应该会挂,也没有看到MSDN上哪儿有写,待后续确认后再更新)
至于为什么要将CLR异常封装成FaultException后抛出,我的理解是:对于异常信息,是序列化后才发布给客户端的,也就是说,客户端也得需要理解这个异常才能反序列化异常信息。因此,客户端必须知道异常的格式,由于WCF的客户端并非只有.net语言才能实现,因此需要发布异常格式,由于CLR的异常比较多,加上还有自定义异常,无法公布所有异常格式,因此,将其统一成FaultException发布,这样客户端才能顺利解析。
了解了这个后,我们就知道InvalidOperationException异常为什么会变成了FaultException异常,但是存在的一个问题是:虽然客户端能感知到调用服务发生了异常,但仍然不知道异常信息,有时无法进行进一步处理。
Debug期间异常信息传递
在前面的异常信息中就有说明:有关该错误的详细信息,请打开服务器上的 IncludeExceptionDetailInFaults (从 ServiceBehaviorAttribute 或从 <serviceDebug> 配置行为)以便将异常信息发送回客户端。它告诉了我们有两个方式可以传递这个异常信息:
- 配置serviceBehaviors,将includeExceptionDetailInFaults设置为true
- 在服务上的ServiceBehaviorAttribute里面设置IncludeExceptionDetailInFaults
这两种方式是等效的,不过建议在配置文件里面使用,统一设置比较方便,也方便统一关闭。
经过这个设置后,再运行客户端代码,这次就可以看到异常信息了:
连异常的调用栈也能看到,方便我们进行异常定位。
<StackTrace> 在 WcfService.Service1.ErrorTest() 位置 Service1.cs:行号24
在 SyncInvokeErrorTest(Object , Object[] , Object[] )
不过,这个在另一方面也暴露了服务器的信息,对于这种网络程序来说是不安全的,因此只建议在Debug的时候使用,从serviceDebug的名字中也可以看出这一点。
构造FaultException
为了安全,前面所说的异常信息获取方式,只能在Debug期间使用,那么,对于Release版本,则需要我们自己手动把运行异常封装成FaultException返回。
public class Service1 : IService1
{
public void ErrorTest()
{
try
{
throw new InvalidOperationException("异常测试");
}
catch (Exception e)
{
throw new FaultException(e.Message);
}
}
}
这次我们就能获取到异常信息了。
对于比较复杂的异常信息,可以自己构造一个FaultException<T>,如下是一个简单的示例:
[ServiceContract]
public interface Iservice
{
[OperationContract]
[FaultContract(typeof(DataAccessFault))]
void Operation();
}
public class Service : Iservice
{
public void Operation()
{
try
{
// Access database …
}
catch (DbException e)
{
DataAccessFault fault = new DataAccessFault();
fault.AdditionalDetails = e.Message;
throw new FaultException<DataAccessFault>(fault);
}
}
}
自己手动构造FaultException的方式比较麻烦,需要在每一个提供的接口中都捕获异常,并重新封装抛出,一来不好看,处理起来也比较麻烦。由于篇幅有限,下篇文章中介绍一个更为简单的方法。
转载于:https://www.cnblogs.com/TianFang/archive/2013/01/02/2841981.html
WCF入门(七)——异常处理1相关推荐
- [WCF编程]1.WCF入门示例
一.WCF是什么? Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,整合了原有的windows通讯的 .net Remotin ...
- 十五天精通WCF——第七天 Close和Abort到底该怎么用才对得起观众
原文:十五天精通WCF--第七天 Close和Abort到底该怎么用才对得起观众 一:文起缘由 写这一篇的目的源自于最近看同事在写wcf的时候,用特别感觉繁琐而且云里雾里的嵌套try catch来防止 ...
- WCF 入门之旅(4): 怎样用客户端调用WCF服务
WCF 入门之旅(4): 怎样用客户端调用WCF服务 前面的demo已经能够跑起来,现在开始考虑用客户端来测试所写的应用了,首先用个普通的应用程序来调用所写的wcf服务吧.其实最后运行wcf服务后的页 ...
- Spring Boot入门——全局异常处理
Spring Boot入门--全局异常处理 参考文章: (1)Spring Boot入门--全局异常处理 (2)https://www.cnblogs.com/studyDetail/p/702758 ...
- [老老实实学WCF] 第七篇 会话
原文:[老老实实学WCF] 第七篇 会话 老老实实学WCF 第七篇 会话 通过前几篇的学习,我们已经掌握了WCF的最基本的编程模型,我们已经可以写出完整的通信了.从这篇开始我们要深入地了解这个模型的高 ...
- WCF入门的了解准备工作
了解WCF, 及WCF入门需要掌握哪里基本概念? 1.准备工作 >1.1 . XML >1.2 . Web Service >1.3 . 远程处理 (RPC) >1.4. 消 ...
- response.end后抛了异常_(七)异常处理
(七)异常处理 异常 异常的体系结构 java.lang.Throwable|-----java.lang.Error:一般不便携针对性的代码进行处理|-----java.lang.Exception ...
- MySQL入门 (七) : 储存引擎与资料型态
1 表格与储存引擎 表格(table)是资料库中用来储存纪录的基本单位,在建立一个新的资料库以后,你必须为这个资料库建立一些储存资料的表格: 每一个资料库都会使用一个资料夹,这些资料库资料夹用来储存所 ...
- 手动抛出异常_(七)异常处理
(七)异常处理 异常 异常的体系结构 java.lang.Throwable|-----java.lang.Error:一般不便携针对性的代码进行处理|-----java.lang.Exception ...
- 服务端增加WCF服务全局异常处理机制
转自:http://www.csframework.com/archive/1/arc-1-20150109-2193.htm 服务端增加WCF服务全局异常处理机制,任一WCF服务或接口方式出现异常, ...
最新文章
- Linux sendmail发送邮件失败诊断案例(一)
- 如何一小时杀入天池OCR比赛前排?
- springcloud 相同服务名_Spring 微服务从入门到入土
- python语言自学-零基础小白学习Python编程语言的正确姿势(纯干货)
- 查看python版本号-怎么查看python版本号
- DFS(二):骑士游历问题
- 解决WSL2中Vmmem内存占用过大问题
- JavaScript之引用类型介绍
- AI 线上峰会 | 人工智能技术解析与实战
- 【2017级面向对象程序设计寒假作业】第4次作业情况
- python中常用的函数有哪些_python里常用的函数类型
- 请描述osi七层模型,并简要概括各层功能
- 昨天我上午下单买的电池,已经到了长沙
- java生成随机数的三种方法
- php汉字转拼音百家姓版,百家姓全文查询,百家姓全文带拼音
- Linux主机安全加固方法使用开源软件fail2ban防护主机
- ERP编制物料清单 金蝶
- 数据库课程设计(电脑配件库存管理系统)
- 网络规划设计师上午真题及解析(2019)
- HTML5 参考手册 ———— 颜色名