【WCF】错误协定声明
在上一篇烂文中,老周给大伙伴们介绍了 IErrorHandler 接口的使用,今天,老周补充一个错误处理的知识点——错误协定。
错误协定与IErrorHandler接口不同,大伙伴们应该记得,上回我们是把自己实现IErrorHandler接口的类型添加到ChannelDispatcher中的,也就是说,IErrorHandler处理的是通道层的错误,它可以捕捉到多个服务操作上发生的错误。而错误协定是面向协定层的,它是通过 FaultContractAttribute 来声明的,这个特性在上一篇文章中我们用过,它应用的目标是方法。故而这个特性是针对某个服务操作而定义的,主要指明在某个服务操作可能会引发的 FaultException<TDetail> 异常,其中的TDetail泛型参数的类型是在FaultContract特性中指定。
在上一篇烂文中提到过,如果是像string、int这些基本类型,是可以直接用的,如果是自定义的类型,则应该将其声明为数据协定,然后在FaultContract特性中作声明。
咱们来实战一下。首先,咱们定一个服务协定。
[ServiceContract(Namespace = "zhou-demo", Name = "runner")]
public interface IDemo
{
[OperationContract(Action = "getNum", ReplyAction = "getNumRes")]
[FaultContract(typeof(ErrorData), Namespace = "zhou-demo/faults", Name = "fault-ct", Action = "fault-back")]
int GetNumber();
}
这个协定没什么重要的事情干,无非就是返回一个整数,待会儿咱们让它返回随机整数。
不过大家注意,我在方法上应用了FaultContract特性,它的构造函数是个Type,这个Type用来指定存放错误详细信息的类型,这个类型就是FaultException<TDetail>中的TDetail的类型。其他属性如Action,Namespace、Name这些,不用我多说了吧,都知道干吗用的,你也可以不设置的,它会自动生成一个默认值。
ErrorData是我自己定义的一个数据协定,请看下面代码。
[DataContract(Namespace = "zhou-demo/fault-data")]
public class ErrorData
{
[DataMember]
public int ErrorNumber { get; set; }
[DataMember]
public string ErrorSource { get; set; }
[DataMember]
public string ErrorMessage { get; set; }
[DataMember]
public string ErrorType { get; set; }
}
这个好懂吧,不必介绍了吧。
当服务操作中发生异常时,可以用ErrorData类来封装自定义的错误信息,WCF会把它序列化,然后塞进SOAP消息中发回给客户端,客户端就可以catch到这些错误数据了。
接下来,实现服务类。
class DemoService : IDemo
{
public int GetNumber()
{
Random rand = new Random();
int n = rand.Next();
if(n % == )
{
ErrorData erdata = new ErrorData
{
ErrorNumber = n,
ErrorSource="人品",
ErrorType="生物机能错误",
ErrorMessage ="运气指数不佳,引发不可修复错误。"
};
throw new FaultException<ErrorData>(erdata);
}
return n;
}
}
这代码没什么技术含量,你如果看不懂,应该写一份30万字的检讨书。随机生成一个整数,如果这个整数可以被3整除,那就抛出异常,否则正常返回这个数值。
服务完成,下面该轮到实例化ServiceHost了,有了Host我们才能调用服务。Host的处理很TMD简单,直接指定:基址 + 服务类型 = 完事。
Uri baseAddress = new Uri("http://localhost:9973");
ServiceHost host = new ServiceHost(typeof(DemoService), baseAddress);
host.Open();
Console.WriteLine("服务已启动。");
……
host.Close();
还记得老周以前说过吧,如果仅仅指定基址,而不定义任何EndPoint的话,Host会自动根据协定个数和基址个数,自动生成默认的终结点。在这个高大上例子中,基址是http方案的,所以生成的终结点默认使用BasicHttpBinding,由于服务类只实现了一个服务协定接口,所以该Host中也就只有一个终结点了。
好了,万事具备,只欠东风了,东风就是客户端调用代码。
Console.WriteLine("请按 Esc 键退出,按任意键调用服务。");
ConsoleKeyInfo keyinfo;
while((keyinfo = Console.ReadKey(true)).Key != ConsoleKey.Escape)
{
EndpointAddress epaddr = new EndpointAddress(baseAddress);
BasicHttpBinding binding = new BasicHttpBinding();
IDemo channel = ChannelFactory<IDemo>.CreateChannel(binding, epaddr);
try
{
int x = channel.GetNumber();
Console.WriteLine($"\n调用结果:{x}。");
}
catch(FaultException<ErrorData> ftex)
{
ErrorData detail = ftex.Detail;
string msg = $"\n错误数字:{detail.ErrorNumber}\n" +
$"错误源:{detail.ErrorSource}\n" +
$"错误类型:{detail.ErrorType}\n" +
$"错误详情:{detail.ErrorMessage}";
Console.WriteLine(msg);
}
catch(FaultException fex)
{
Console.WriteLine(fex.Message);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
IClientChannel client = (IClientChannel)channel;
client.Close();
}
为了能够在控制台应用程序中多次调用服务(整数是随机生成,不能保证每次都抛异常),老周做了些处理,按任意键来调用服务,当然不能弄成死循环,为了使循环不死,我留了个出口——按Esc键。
如果在服务器上果真引发了FaultException<TDetail>,那么,在客户端就可以捕捉到该异常。服务器引发异常后会数据对象序列化,传到客户端后,会进行反序列化。
示例运行结果如下图所示。

好了,知识点补完了,老周得准备吃lunch了,今天是国庆长假第二天,下午老周要去朋友H家里看现场水墨绘画,据说有不少妹子在那里。
===================================================
很久没讲故事了,这回就讲一讲老周为什么会进入IT界吧。
其实原因也极其简单,也不是什么远大志向,老周之所以会进入IT领域,就是因为喜欢编程,纯粹就是爱编程,不等于爱做项目,老周很讨厌做项目。
还是孔爷爷说得好,“知之者不如好之者,好之者不如乐之者”,对老周而言,除了卖保险之外,什么行业都可以进,要不是热爱编程,老周是不会选择走IT道路。而编程里面,犹爱.NET。
所以,以后你要是想跟老周讨论编程问题,那就只讨论编程上的事,不要跟我讨论怎么找到好工作,找工作那是你的事,跟我没关系,也不要讨论.net有什么前景之类的话题,那是匹夫才讨论的问题。不过,最近些天,好像又有些不学无术的人,又在搞.NET与Java之争,那些东西在老周眼里,等同于看一场相声表演而已。
反正老周只告诉你一句话:我就是热爱.NET。
如果你喜欢.NET,欢迎你看看老周写的烂文章;如果你不喜欢.NET,那无所谓,你可以无视老周的博客。但是,老周不允许有人在博客评论里面说不文明的言论。心诚则与君交,心不诚则与君绝。
【WCF】错误协定声明的更多相关文章
- WCF初探-20:WCF错误协定
WCF错误协定概述 在所有托管应用程序中,处理错误由 Exception 对象表示. 在基于 SOAP 的应用程序(如 WCF 应用程序)中,服务方法使用 SOAP 错误消息来传递处理错误信息. SO ...
- 【WCF】错误处理(三):错误协定
最近折腾换电脑的事,博客就更新慢了点.好,不废话,直入正题. 前面老周介绍过,SOAP消息中的错误信息是用一个 Fault 元素来包装的,前面老周也讲了其中的 FaultCode 元素,即可以对错误信 ...
- WCF初探-15:WCF操作协定
前言: 在前面的文章中,我们定义服务协定时,在它的操作方法上都会加上OperationContract特性,此特性属于OperationContractAttribute 类,将OperationCo ...
- WCF初探-14:WCF服务协定
前言: 在前面的文章中,我们定义的服务协定上都会有一个ServiceContract的特性来修饰,这是因为服务契约的实现要靠ServiceContractAttribute 属性定义,然后使用一个或多 ...
- WCF错误处理
介绍 WCF(Windows Communication Foundation) -异常处理:一般Exception的处理,FaultException和FaultException<T> ...
- WCF初探-19:WCF消息协定
WCF消息协定概述 在生成 WCF应用程序时,开发人员通常会密切关注数据结构和序列化问题,而不必关心携带数据的消息结构. 对于这些应用程序,为参数或返回值创建数据协定的过程很简单.但是,有时完全控制 ...
- WCF错误:由于目标计算机积极拒绝,无法连接;127.0.0.1:3456
问题描述 最近Windows打完补丁,原来部署在本机的WCF无法连接:出现如下WCF错误:由于目标计算机积极拒绝,无法连接:127.0.0.1:3456 解决方案 检查一下本机的服务:NetTcpAc ...
- WCF初探-16:WCF数据协定之基础知识
数据协定概念 “数据协定”是在服务与客户端之间达成的正式协议,用于以抽象方式描述要交换的数据. 也就是说,为了进行通信,客户端和服务不必共享相同的类型,而只需共享相同的数据协定. 数据协定为每一个做数 ...
- WCF初探-18:WCF数据协定之KnownType
KnownTypeAttribute 类概述 在数据到达接收终结点时,WCF 运行库尝试将数据反序列化为公共语言运行库 (CLR) 类型的实例.通过首先检查传入消息选择为反序列化而实例化的类型,以确定 ...
随机推荐
- JAVA回调机制(CallBack)详解
序言 最近学习java,接触到了回调机制(CallBack).初识时感觉比较混乱,而且在网上搜索到的相关的讲解,要么一言带过,要么说的比较单纯的像是给CallBack做了一个定义.当然了,我在理解了回 ...
- 【深入浅出jQuery】源码浅析--整体架构
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- nodejs进阶(1)—输出hello world
下面将带领大家一步步学习nodejs,知道怎么使用nodejs搭建服务器,响应get/post请求,连接数据库等. 搭建服务器页面输出hello world var http = require ...
- Android业务组件化之子模块SubModule的拆分以及它们之间的路由Router实现
前言: 前面分析了APP的现状以及业务组件化的一些探讨(Android业务组件化之现状分析与探讨),以及通信的桥梁Scheme的使用(Android业务组件化之URL Scheme使用),今天重点来聊 ...
- dubbox微服务实例及引发的“血案”
Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成. 主要核心部件: Remoting: 网络通信框架 ...
- HIVE教程
完整PDF下载:<HIVE简明教程> 前言 Hive是对于数据仓库进行管理和分析的工具.但是不要被“数据仓库”这个词所吓倒,数据仓库是很复杂的东西,但是如果你会SQL,就会发现Hive是那 ...
- hibernate的基本xml文件配置
需要导入基本的包hibernate下的bin下的required和同bin下optional里的c3p0包下的所有jar文件,当然要导入mysql的驱动包了.下面需要注意的是hibernate的版本就 ...
- ECharts数据图表系统? 5分钟上手!
目录: 前言 简介 方法一:模块化单文件引入(推荐) 方法二:标签式单文件引入 [前言] 最近在捣鼓各种插件各种框架,发现这个ECharts还是比较不错的,文档也挺全的,还是中文的,给大家推荐一下. ...
- vim+vundle配置
Linux环境下写代码虽然没有IDE,但通过给vim配置几个插件也足够好用.一般常用的插件主要包括几类,查找文件,查找符号的定义或者声明(函数,变量等)以及自动补全功能.一般流程都是下载需要的工具,然 ...
- win10电脑优化
Windows10必做的优化 --道心 关闭服务 右键点击"此电脑",选择"管理",进入"计算机管理"窗口. 在左侧的菜单选择"服 ...