十五天精通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:

public class HomeService : IHomeService
    {
        public Student Get(string id)
        {
            //这里必然会抛出异常。。。
            var result = Convert.ToInt32(id) / Convert.ToInt32("0");

            return new Student() { ID = Convert.ToInt32(id), Name = "hxc", SNS = "001" };
        }
    }

Client:
public class Program1
    {
        static void Main(string[] args)
        {
            using (HomeServiceClient client = new HomeServiceClient())
            {
                try
                {
                    var result = client.Get("1");
                }
                catch (Exception ex)
                {

                }
            }
        }
    }

 

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

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

using (HomeServiceClient client = new HomeServiceClient())
            {
                try
                {
                    var result = client.Get("1");
                }
                catch (Exception ex)
                {
                    client.Abort();
                }
            }

但是这么写有个什么问题呢???就是不管客户端抛出什么异常,我们都习惯用基类异常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等等自定义信息。

public class HomeService : IHomeService
    {
        public Student Get(string id)
        {
            try
            {
                //这里必然会抛出异常。。。
                var result = Convert.ToInt32(id) / Convert.ToInt32("0");

                return new Student() { ID = Convert.ToInt32(id), Name = "hxc", SNS = "001" };
            }
            catch (Exception ex)
            {
                var reason = new FaultReason("你这个战斗力只有五的渣渣。。。 这么简单的错误都出来了,搞个鸡巴毛");

                var code = new FaultCode("500");

                var faultException = new FaultException(reason, code, "是Get这个王八蛋");

                throw faultException;
            }
        }
    }

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

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

相关文章
十五天精通WCF——第十四天 一起聊聊FaultException
原文:十五天精通WCF——第十四天 一起聊聊FaultException       我们在玩web编程的时候,可能你会不经意的见到一些http500的错误,我想你应该不会陌生的,原因你应该也知道,服务器异常嘛, 这时候clr会把这个未处理的异常抛给iis并且包装成http500的错误返回到客户端,就比如下面这样。
1164 0
|
9月前
|
前端开发
WCF更新服务引用报错的原因之一
WCF更新服务引用报错的原因之一
|
8月前
|
C# 数据安全/隐私保护
c#如何创建WCF服务到发布(SqlServer版已经验证)
c#如何创建WCF服务到发布(SqlServer版已经验证)
38 0
|
8月前
|
安全 数据库连接 数据库
WCF服务创建到发布(SqlServer版)
在本示例开始之前,让我们先来了解一下什么是wcf? wcf有哪些特点? wcf是一个面向服务编程的综合分层架构。该架构的项层为服务模型层。 使用户用最少的时间和精力建立自己的软件产品和外界通信的模型。它使得开发者能够建立一个跨平台的安全、可信赖、事务性的解决方案。且能与已有系统兼容写作。 简单概括就是:一组数据通信的应用程序开发接口。
59 0
Visual Studio 2022 创建 WCF服务 找不到
Visual Studio 2022 创建 WCF服务 找不到
|
C++
WCF基础教程(二)——解析iis8和iis8.5+VS2013发布wcf服务问题
WCF基础教程(二)——解析iis8和iis8.5+VS2013发布wcf服务问题
102 0
WCF基础教程(二)——解析iis8和iis8.5+VS2013发布wcf服务问题
WCF使用纯代码的方式进行服务寄宿
服务寄宿的目的是为了开启一个进程,为WCF服务提供一个运行的环境。通过为服务添加一个或者多个终结点,使之暴露给潜在的服务消费,服务消费者通过匹配的终结点对该服务进行调用,除去上面的两种寄宿方式,还可以以纯代码的方式实现服务的寄宿工作。
850 0
|
Windows
WCF服务寄宿到IIS
一.WCF简介: Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Windows 通讯开发平台。整合了原有的windows通讯的 .net Remoting,WebService,Socket的机制,并融合有HTTP和FTP的相关技术。
1048 0
WCF服务自我寄宿
WCF服务的寄宿方式 WCF寄宿方式是一种非常灵活的操作,可以寄宿在各种进程之中,常见的寄宿有: IIS服务、Windows服务、Winform程序、控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者方便、高效提供服务调用。
996 0