十五天精通WCF——第十四天 一起聊聊FaultException

  

   我们在玩web编程的时候,可能你会不经意的见到一些http500的错误,我想你应该不会陌生的,原因你应该也知道,服务器异常嘛,

这时候clr会把这个未处理的异常抛给iis并且包装成http500的错误返回到客户端,就比如下面这样。

从这张图中,我故意输入了xss字符,然后的然后,web程序自爆异常,其实我想表达的意思就是,虽然说web程序抛异常了,但不代表iis就

挂了,所以iis还是需要给客户端做出反馈,这就有了http header,和body信息,同样的道理,wcf的服务器异常机制也是这样。。。service

抛出了异常,不代表console就挂了,console要做的事情就是把这个异常包装起来丢给调用方,而wcf是怎么包装的呢???就是用了这篇所

说的FaultException。。。

一:FaultException

1. faultexception是干什么的?

  刚才我也说了,这个异常就是wcf来包装远程错误的,具体的类含义就是表示“SOAP错误“,如果你够细心的话,你还会发现到它有个属性

叫Serializable,有了它,这个叼毛就可以序列化到Soap消息中,对伐???

2. 如果挖出faultexception?

  挖出这个exception的方法有很多,比如我来造一个“除以0”的异常,如下所示:

Service:

 1     public class HomeService : IHomeService
 2     {
 3         public Student Get(string id)
 4         {
 5             //这里必然会抛出异常。。。
 6             var result = Convert.ToInt32(id) / Convert.ToInt32("0");
 7
 8             return new Student() { ID = Convert.ToInt32(id), Name = "hxc", SNS = "001" };
 9         }
10     }

Client:

 1     public class Program1
 2     {
 3         static void Main(string[] args)
 4         {
 5             using (HomeServiceClient client = new HomeServiceClient())
 6             {
 7                 try
 8                 {
 9                     var result = client.Get("1");
10                 }
11                 catch (Exception ex)
12                 {
13
14                 }
15             }
16         }
17     }

看到了没有,虽然wcf的service已经抛出异常了,但是还是被clr用Faultexception包装起来了,正如你看到了s:Fault节点,仔细往下看的话,

你还会看到faultcode,faultstring,detail等等属性节点,那下面有个问题就来了,我们平时在Client端都习惯这么写。

 1             using (HomeServiceClient client = new HomeServiceClient())
 2             {
 3                 try
 4                 {
 5                     var result = client.Get("1");
 6                 }
 7                 catch (Exception ex)
 8                 {
 9                     client.Abort();
10                 }
11             }

但是这么写有个什么问题呢???就是不管客户端抛出什么异常,我们都习惯用基类异常Exception捕获,但是wcf有一点非常恶心的就是,

它的异常信息非常的少,第一眼根本看不出个一二三,这是因为所有的异常你都用顶级的exception捕获,自然你能知道的信息就非常少,

这也很正常,如果你想要更详细的信息,你是不是应该在Client端写上更具体的异常捕获类呢???就比如你现在已经知道的FaultException

是因为服务器的错误都是由它处理的。

如果现在你按照上图中所coding的那样,你是不是对异常信息可以了解的更深,起码你知道这个异常的抛出,绝逼是因为通道是正常的,只是

servcie抛出异常了而已。。。那你可能要问了,我这话的言外之意就是还有其他异常类也会捕获wcf抛出的异常,对的,比如说你的信道出现

故障,这时候会抛出一个“通信异常(CommunicationException)”。

三:如何挖出“通信异常”

    挖出这个异常,也是很简单的,现在我们需要使用”会话级别“的binding,比如说nettcpbinding,wshttpbinding,这里的话,我选择

后者,因为是这样的,第一次服务器抛异常以后,客户端和服务器端通信信道就会关闭,如果你在客户端不重新new一个client,那么这时候你

第二次再使用client的话,这个时候就会产生“信道故障“,抛出CommunicationException,而当你看到CommunicationException的时候,

你可以非常有自信的说,老子的wcf根本就没有连接到service,而是在client端就被杀死了。。。下面我演示一下。

四:自定义FaultException

  现在你应该知道了,只要是Servcie的Exception都会抛出 FaultException,对吧,而且你用Fiddler观察的话,也看的出其中的faultcode

和faultstring貌似都不是很详细,那我就有一个想法了,既然wcf会自己给我包装个FaultException,那何不我自己就在发生异常的时候自己包

装一个自定义的FaultException,然后我可以包装一些我自己想要告诉客户端的信息,这样的话是不是灵活性非常的大呢???想法很不错,wcf

也是恩准这么做的,下面我把service的get方法更改如下,在FaultException中自定义Reason,Code,Action等等自定义信息。

 1  public class HomeService : IHomeService
 2     {
 3         public Student Get(string id)
 4         {
 5             try
 6             {
 7                 //这里必然会抛出异常。。。
 8                 var result = Convert.ToInt32(id) / Convert.ToInt32("0");
 9
10                 return new Student() { ID = Convert.ToInt32(id), Name = "hxc", SNS = "001" };
11             }
12             catch (Exception ex)
13             {
14                 var reason = new FaultReason("你这个战斗力只有五的渣渣。。。 这么简单的错误都出来了,搞个鸡巴毛");
15
16                 var code = new FaultCode("500");
17
18                 var faultException = new FaultException(reason, code, "是Get这个王八蛋");
19
20                 throw faultException;
21             }
22         }
23     }

好了,大概就说这么多了,我的目的也很简单,在写wcf的client的时候,尽量做到异常越具体越好,这样方便我们尽可能快的排查问题,因为

wcf的异常信息真的太tmd坑爹了!!!减轻痛苦,从小做起~~~

时间: 2024-10-10 09:24:02

十五天精通WCF——第十四天 一起聊聊FaultException的相关文章

十五天精通WCF——第十天 学会用SvcConfigEditor来简化配置

我们在玩wcf项目的时候,都是自己手工编写system.serviceModel下面的配置,虽然在webconfig中做wcf的服务配置的时候,vs提供大多 数的代码提示,但对于不太熟悉服务配置的小鸟们来说,有些困难,而且一些服务配置也容易遗漏,大多情况下,我们都是copy一份服务配置,然 后在服务配置上面修修改改,对吧...其实呢,.net给我们提供了一个强大的scvconfigeditor这个工具化的软件来帮助我们生成wcf的配置,是 不是很神奇??? 一:工具在何处 当然在无比牛逼的Mic

十五天精通WCF——第四天 你一定要明白的通信单元Message

原文:十五天精通WCF--第四天 你一定要明白的通信单元Message 转眼你已经学了三天的wcf了,是不是很好奇wcf在传输层上面到底传递的是个什么鸟毛东西呢???应该有人知道是soap,那soap这叼毛长得是什么 样呢?这一篇我们来揭开答案... 一:soap到底长成什么样子 为了能看清soap长的啥样,我可以用强大的Fiddler来监视一下,突然好激动啊!!! 1.Server 1 static void Main(string[] args) 2 { 3 ServiceHost host

十五天精通WCF——第一天 三种Binding让你KO80%的业务

原文:十五天精通WCF--第一天 三种Binding让你KO80%的业务 转眼wcf技术已经出现很多年了,也在.net界混的风生水起,同时.net也是一个高度封装的框架,作为在wcf食物链最顶端的我们所能做的任务已经简单的不能再简单了, 再简单的话马路上的大妈也能写wcf了,好了,wcf最基本的概念我们放在后面慢慢分析,下面我们来看看神奇的3个binding如何KO我们实际场景中的80%的业务场景. 一:basicHttpBinding 作为入门第一篇,也就不深入谈谈basic中的信道栈中那些啥

十五天精通WCF——第九天 高级玩法之自定义Behavior

原文:十五天精通WCF--第九天 高级玩法之自定义Behavior 终于我又看完了二期爱情保卫战,太酸爽了,推荐链接:http://www.iqiyi.com/a_19rrgublqh.html?vfm=2008_aldbd,不多说,谁看谁入迷,下面言归正传, 看看这个很有意思的Behavior. 一: Behavior这个泼妇的厉害   在前面的文章中,我也清楚的说明了整个wcf通信流,而Behavior这个泼妇可以在wcf通信流中的任何地方插上一脚,蛮狠无比,利用的好,让你上天堂,利用的不

十五天精通WCF——第七天 Close和Abort到底该怎么用才对得起观众

一:文起缘由 写这一篇的目的源自于最近看同事在写wcf的时候,用特别感觉繁琐而且云里雾里的嵌套try catch来防止client抛出异常,特别感觉奇怪,就比如下面的代码. 1 public void StartNormalMarketing(int shopId, List<int> marketingIdList) 2 { 3 4 using (SendEventMarketingService.DistributeServiceClient client = new SendEventM

十五天精通WCF——第十二天 说说wcf中的那几种序列化

我们都知道wcf是由信道栈组成的,在我们传输的参数走到传输信道层之前,先需要经过序列化的过程,也就是将参数序列化为message,这篇 我们就来说说这里的序列化,蛮有意思的,可能初学者也明白,在wcf中默认的序列化是DataContractSerializer,确实是这样,不过wcf在信道中 其实不仅仅支持DataContractSerializer,它还支持其他类型的序列化,比如XmlSerializer,NetDataContractSerializer以及DataContractJson

十五天精通WCF——第十一天 如何对wcf进行全程监控

说点题外话,我们在玩asp.net的时候,都知道有一个叼毛玩意叫做“生命周期”,我们可以用httpmodule在先于页面的page_load中 做一些拦截,这样做的好处有很多,比如记录日志,参数过滤,全局登录验证等等...在wcf里面的话也是有类似的功能,第一种就是在 endpoint中加上runtime的behavior,这样的话就可以先于“服务方法”做拦截,第二种方法呢,也就是我们这一篇所说的全程监控,俗称 ”诊断功能”. 一:诊断 我也说了,“诊断”这是wcf的一个专业术语,意思也就是监控

十五天精通WCF——第六天 你必须要了解的3种通信模式

wcf已经说到第六天了,居然还没有说到这玩意有几种通信模式,惭愧惭愧,不过很简单啦,单向,请求-响应,双工模式,其中的第二种“请求-响应“ 模式,这个大家不用动脑子都清楚,这一篇我大概来分析下. 一:“请求-响应“模式   如果你看了我上一篇的博文,你应该非常清楚这种类似“本地调用”的方式,wcf同样也分为“同步”和“异步”两种,不过不管是异步还是同步,最终都逃 不过是“请求-响应”这个事实,对吧. 1: 同步方式 这种方式我想没什么好说的,前面几篇我已经说的非常清楚了,具体使用方法可以参考我的

十五天精通WCF——第二天 告别烦恼的config配置

经常搞wcf的基友们肯定会知道,当你的应用程序有很多的“服务引用”的时候,是不是有一种疯狂的感觉...从一个环境迁移到另外一个环境,你需要改变的 endpoint会超级tmd的多,简直就是搞死了人...好了,这篇我们来看看如何最小化配置. 一:精简service的config配置 就像上一篇的代码一样,我的service端的config配置如下: 1 <?xml version="1.0" encoding="utf-8" ?> 2 <config