WCF 基础之契约(Contract)[转]

WCF 基础之契约(Contract)[转]

1. WCF 基础之契约(Contract
契 约(Contract)是 WCF 的消息标准,告知客户端如何与服务器联系交互。契约是平台中立的,也就说我们可以使用其它平台(包括开发和系统平台)来调用服务。WCF 中包含 4 种契约,分别是用于定义服务操作(Operations)的 Service Contract,定义自定义数据结构的 Data Contract,定义错误异常的 *Fault Contract,以及直接控制消息格式的 Message Contract。它们算是WCF的核心之一,如果你要使用WCF,就需要了解他们。

  • Service contracts : 定义客户端可以使用哪些服务操作。
  • Data contracts : 定义服务传输的数据类型。WCF 定义了一些隐式数据契约,像 int、string 等,更多时候我们需要使用 DataContractAttribute 显式定义那些自定义数据结构的数据契约。
  • Fault contracts : 定义服务引发的错误信息,以及如何传递这些异常给客户端。
  • Message contracts : 允许我们直接操控服务消息内容和格式,可以是类型化或无类型的。

2. 服务契约(Service Contract)
一般情况下,我们用接口(Interface)来定义服务契约(Service Contract)。虽然我们也可以使用 Class,但使用接口的好处更明显一些。便于契约的继承,不同根的类型可以自由实现相同的契约。

  • 同一服务类型可以实现多个契约。
  • 和接口隔离原则相同,我们随时可以修改服务类型。
  • 便于制定版本升级策略,让新老版本的服务契约同时使用。

WCF 使用特性 ServiceContractAttribute 标定服务契约,OperationContractAttribute 标定服务方法。

ServiceContract public interface ICalculate { OperationContract double Add(double a, double b); }


OperationContract 只能用于 Method,只有添加了此特性的方法才能被客户端调用。它甚至可以用来标注私有方法,这显然超出了面向对象的规则,而更多的是 SOA 的方式。SOA 只是分布式系统的架构体系,在架构体系内部我们依然采取面向对象的原则来编码,所以标注私有方法是不被推荐的,这也是使用接口作为服务契约的一个好处(接 口中无法定义私有方法)。

异步 Asynchronous
在WCF中,如果在服务契约中建立了异步方法,那么客户端代理将同时存在异步和非异步版本。
设置OperationContract的AsyncPattern:=True 即可以建立异步方法

双向通讯 Duplex
通 过在服务契约中指定CallbackContract:=GetType(ICalculatorDuplexCallback)即可以指定回调接口。 在回调的时候,由于系统会确认执行过程。所以,为了避免死锁,一般加上(IsOneWay:=True)>关键字。

Oneway
在我们的程序中,有些服务是不需要确认是否到达到服务器的或者没有返回值的。这个时候我们可以设置IsOneWay:=True 这样,WCF便不会等到执行完才返回了。

Session
虽然在SOA中,提议每个服务请求都是独立的。但是,我们有时候需要保存一些数据,比如:用户ID。这个时候,我们可以把这个数据保存回话中。 WCF中,支持3种回话模式
1. Pre-Call: 服务实例被释放,客户端抛出 FaultException,客户端代理对象无法继续使用。
2. Pre-Session: 服务实例被释放,会话终止。客户端抛出 FaultException,客户端代理对象无法继续使用。
3. Singleton: 服务实例依旧运行,会话终止。客户端抛出 FaultException,客户端代理对象无法继续使用。

流 Stream
在WCF中也支持流传输,这时候,有点类似打开TCP端口~。对于传输大量数据比较有效率,例如:上传文件。记得在使用的时候配置好最大消息的大小

ServiceContract 的属性

  • ConfigurationName: 其设置信息在配置文件中的名称。
  • Name / Namespace:自定义该服务契约的名称和命名空间。建议设置服务契约的 Name 和 Namespace,这样生成的客户端的代理文件会使用自定义名称来命名相关代理类型,即便我们日后对服务器端的契约名称进行重构也不会影响到客户端。
  • SessionMode:设置服务契约的 Session 方式,包括 Allowe、NotAllowed、Required。SessionMode 需要相应的 Binding 支持,默认情况下会自动启用,另外我们还会和 ServiceBehaviorAttribute.InstanceContextMode 配合使用来管理服务对象的生命周期。
  • CallbackContract:设置 duplex 模式时的回调类型。
  • ProtectionLevel:指定消息保护方式,可以对消息进行加密和签名处理。
  • OperationContract 的属性
  • AsyncPattern:用于定义异步服务方法。
  • IsInitiating:指示服务方法能否启动一个 Session。
  • IsTerminating:指示服务方法调用完成是否结束 Session。

3. 数据契约(Data Contract)
数据契约(Data Contract)是用来标识用户自定义类型和序列化。
DataContractAttribute、 DataMemberAttribute 来标注自定义数据类型,这样我们就可以在服务方法中传递复杂的数据体了。使用之前,我们需要添加 System.Runtime.Serialization.dll 引用。由此我们可以看出其基本的开发模式,那就是使用 ServiceContract、OperationContract 执行运算,而使用 DataContract、DataMember 作为可序列化的数据载体。当然,我们也可以使用 "Serializable" 代替 "DataContract"。
其实,数据契约主要是定义数据的格式(契约)。DataMember()是告诉序列化引擎要序列化的那个部分(关于序列化,注意一点,反序列化时可以访问任一字段,作用域关键字不起作用,这可能会暴露安全问题。)

        DataContract public struct Number 
{
DataMember public double Num1;
DataMember public double Num2;
public Number(double num1, double num2)
{
this.Num1 = num1;
this.Num2 = num2;
}
}
复制代码

DataContract 的属性
Name / Namespace:自定义名称和命名空间。


DataMember 的属性
Name:自定义名称。
IsRequired:指示该成员序列化前必须被赋值。

DataContractSerializer 实际上序列化是一个过程,不过这个过程大多徐情况下被系统自动实现了。默认情况下,WCF 使用 DataContractSerializer 引擎对相关参数进行序列化,这也是 WCF 推荐的方式。另外一个选择是 XmlSerializer,也就是 ASP.NET Web Service 所使用的序列化引擎。XmlSerializer 仅支持 DataContractSerializer 所支持的部分类型,但它允许你使用 XmlAttributeAttribute 等特性对序列化生成的 XML 进行更多的控制。

DataContractSerializer 支持的类型:
支持所有的基本类型,还包括 XmlElement 和 DateTime 这样的常用类型。
支持使用 DataContractAttribute 标记的类型。
支持使用 SerializableAttribute 标记或者实现 ISerializable 接口的类型。
实现 IXmlSerializable 接口的类型。
大多数集合(含泛型)类型,包括常用的 Array、List、IList 等。

KnownTypes
在OO中,对象继承是很常见的,但如果在WCF直接使用继承后,实际上被分成了2个独立的类。这时就需要使用KnownType来标识,这样在客户端生成代理后就变成继承的了。
还可以通过配置文件指定

4. 消息契约(Message Contract)
消息契约可以算是数据契约的一个分类,专为SOAP而生的。可以控制消息的格式。数据是放在Header 还是Body中。

非类型化(Untyped)
可以通过System.ServiceModel.Channels.Message类来直接构造消息,不过这个必须指定动作的地址,用来确定是那个操作被执行。 这样变可以不用构建类型了,不过会很累。。

非包装(Unwrapped)
WCF对消息序列化的时候,可以决定是否对消息进行包装。 如果,和其他系统整合的话,可能需要去掉包装,手动控制。

样式
可以通过设置XmlSerializerFormat的Style和Use可以使用样式

使用XMLReader
可以通过Message的GetReaderAtBodyContents 可以获取消息的XML部分

5. 错误契约(Fault Contract)
错误契约Fault Contract主要是来告诉一个服务或操作产生错误后,这个消息是什么样子的。 在SOA中,并没有限制客户端是什么平台,事实上,连服务端也是。只有契约没有变。

======================================华丽的分割线=================================================

在WCF中,契约分为四种,它们分别为:

  1. 用于定义服务操作的服务契约:Service Contract

这种级别的契约又包括两种:ServiceContract和OperationContract

ServiceContract用于类或者结构上,用于指示WCF此类或者结构能够被远程调用,而OperationContract用于类中的方法(Method)上,用于指示WCF该方法可被远程调用。

  [ServiceContract]

public interface ICalculate

{

[OperationContract]

double Add(double a, double b);

}
复制代码

 

  1. 用于自定义数据结构的数据契约:Data Contract

数据契约也分为两种:DataContract和DataMember.DataContract用于类或者结构上,指示 WCF此类或者结构能够被序列化并传输,而DataMember只能用在类或者结构的属性(Property)或者字段(Field)上,指示WCF该属 性或者字段能够被序列化传输。
我们还可以使用 DataContractAttribute、DataMemberAttribute 来标注自定义数据类型,这样我们就可以在服务方法中传递复杂的数据体了。使用之前,我们需要添加 System.Runtime.Serialization.dll 引用。由此我们可以看出其基本的开发模式,那就是使用 ServiceContract、OperationContract 执行运算,而使用 DataContract、DataMember 作为可序列化的数据载体。当然,我们也可以使用 "[Serializable]" 代替 "[DataContract]"。

 [DataContract]

public class User

{

int _age = 27;

[DataMember]

public int Age

{

    get { return _age; }

    set { _age = value; }

  }

  string _userName = "wang.yq";

  [DataMember]

  public string UserName

  {

    get { return _userName; }

    set { _userName = value; }

   }

}
复制代码


用于自定错误异常的异常契约:Fault Contract

FaultContract用于自定义错误异常的处理方式,默认情况下,当服务端抛出异常的时候,客户端能接收到异常信息的描述,但这些描述往往格 式统一,有时比较难以从中获取有用的信息,此时,我们可以自定义异常消息的格式,将我们关心的消息放到错误消息中传递给客户端,此时需要在方法上添加自定 义一个错误消息的类,然后在要处理异常的函数上加上FaultContract,并将异常信息指示返回为自定义格式。

  1. 用于控制消息格式的消息契约:Message Contract

简单的说,它能自定义消息格式,包括消息头,消息体,还能指示是否对消息内容进行加密和签名。

ServiceContract

  • ConfigurationName: 其设置信息在配置文件中的名称。
  • Name / Namespace:自定义该服务契约的名称和命名空间。建议设置服务契约的 Name 和 Namespace,这样生成的客户端的代理文件会使用自定义名称来命名相关代理类型,即便我们日后对服务器端的契约名称进行重构也不会影响到客户端。
  • SessionMode:设置服务契约的 Session 方式,包括 Allowe、NotAllowed、Required。SessionMode 需要相应的 Binding 支持,默认情况下会自动启用,另外我们还会和 ServiceBehaviorAttribute.InstanceContextMode 配合使用来管理服务对象的生命周期。
  • CallbackContract:设置 duplex (双向通信)模式时的回调类型。
  • ProtectionLevel:指定消息保护方式,可以对消息进行加密和签名处理。

OperationContract

  • AsyncPattern:用于定义异步服务方法。
  • IsInitiating:指示服务方法能否启动一个 Session。
  • IsTerminating:指示服务方法调用完成是否结束 Session。

DataContract

  • Name / Namespace:自定义名称和命名空间。

DataMember

  • Name:自定义名称。
  • IsRequired:指示该成员序列化前必须被赋值。

 

契约是独立于平台的么?

    WCF作为一种能够跨平台的体系框架,其应用肯定会有异构,异网的情况发生,那么作为通讯依据的契约能否自动适用于上述情况呢?答案是肯定的,契约是独立 于平台之外的,它只约束通讯的双方应该遵守什么样的规则,而丝毫不管双方各自采用的是什么样的技术和什么样的操作系统,也只有这样,WCF才能有真正的生 命力。

契约和以往哪种技术比较相像,又有什么不同?

    如果非要拿契约和以往的技术相比较的话,契约和asp.net xml web service的声明性编程模型甚是相似,比如在web service中在类上标记WebServiceAttribute便可以将此类用于远程调用,而将方法添加WebMethondAttribute也可 以将其暴露给远程客户端,这和WCF中的ServiceContract和OperationContract简直如出一辙,但不同的是,WCF中的契约 要比Xml Web Service中的要详尽的多,比如ServiceContract和OperationContract可以直接使用在接口上面,而实现该接口的类就继 承了这种契约声明,自动拥有契约所规范的动作和行为,这就使得程序员更方便的使用面向接口的编程方式,可以使同一服务拥有不同的实现,在新旧版本升级的同 时,能够使新老版本共同运行。

posted on 2010-10-05 16:40 搏击的小船 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/guanjie20/archive/2010/10/05/2382206.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/495741.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MFC 最详细入门教程

From:https://blog.csdn.net/wang18323834864/article/details/78621633/ Visual Studio 2019:https://visualstudio.microsoft.com/zh-hans/ 鸡啄米 ----- VS2010/MFC编程入门教程之目录和总结:http://www.jizhuomi.com/software/257.html …

没中、美这么大的统一市场,欧盟人工智能发展面临双重挑战

来源:澎湃新闻 作者:胡逸涵为在人工智能领域追赶中美两国,近日,欧盟将2020年前对人工智能(AI)的投资额增加约70%,至15亿欧元。欧盟希望到2020年底,整个欧盟在AI技术领域&#xff0…

人生的闲言碎语

1.人的一生 选对老师,智慧一生;选对伴侣,幸福一生;选对环境,快乐一生;选对朋友,甜蜜一生;选对行业,成就一生。 2.头头是道 人生一世,要起好头:…

Dom4j完整教程~将文档写入XML文件

1.文档中全为英文,不设置编码,直接写入. XMLWriter writer new XMLWriter(new FileWriter("output.xml")); writer.write(document); writer.close(); 2.文档中含有中文,设置编码格式再写入. OutputFormat format OutputFormat.createPrettyPrin…

error LNK2019: 无法解析的外部符号 WinMain,该符号在函数 int __cdecl invoke_main(void)”中被引用

From:https://blog.csdn.net/u012570056/article/details/74639894 一,问题描述 MSVCRTD.lib(exe_winmain.obj) : error LNK2019: 无法解析的外部符号 WinMain,该符号在函数 "int __cdecl invoke_main(void)" (?invoke_mainYAHXZ…

德国人工智能研究中心波尔特:人工智能与工业4.0并驾齐驱

来源:科技日报摘要:2013年德国政府提出的“工业4.0”战略就涵盖了人工智能。“工业4.0”战略着重在制造业等领域相互利用。以深度学习、自我升级为主要特征的人工智能有望将人类各方面智能拓展到极限,从而在各领域做到极致。人工智能的研发在…

用javascript生成指定范围的随机数

1. 从1开始 至 任意值 linenum parseInt(Math.random()*上限1); 2. 从任意值开始 至 任意值 linenum parseInt(Math.random()*(上限-下限1)下限); 上面的公式使用了 parseInt(), 因此要加1; 如果使用 Math.ceil() 则不需要加1, 习惯于这样写... 1. 示例1 (直接进行生成随机数操…

Dom4j完整教程~字符串与XML的转换

1.将字符串转化为XML String text "<members> <member>sitinspring</member> </members>"; Document document DocumentHelper.parseText(text); 2.将文档或节点的XML转化为字符串. SAXReader reader new SAXReader(); Docu…

C++ 基本数据类型 的 字节数

From&#xff1a;https://www.cnblogs.com/qiumingcheng/p/7824919.html C语言入门经典——基础知识&#xff08;数据类型&#xff09;&#xff1a;https://blog.csdn.net/weixin_42167759/article/details/80404815 闲聊c/c: 各平台下基本数据类型的字节长度&#xff1a;htt…

无法找到或创建字体'SansSerif'.某些字符可能无法正确显示或打印。

无法找到或创建字体SansSerif.某些字符可能无法正确显示或打印。原因&#xff1a;繁体CAD生成的PDF造成的。/Files/cnaspnet/SansSerif.rar 转载于:https://www.cnblogs.com/cnaspnet/archive/2010/10/20/1856890.html

协作机器人的江湖:把人放在首位

来源&#xff1a;机器人创新生态 作者&#xff1a;张有凤远离硅谷及亚洲电子产业中心的地方&#xff0c;一个拥有许多灵魂的小创业公司正在掀起波澜。在伊利湖东端&#xff0c;一个由丹麦移民创办的公司正在布法罗市中心的所有地方建造移动计算机。在美国平板制造厂商Bak的厂…

Dom4j完整教程~dom4j的事件处理模型涉及的类和接口

1、类&#xff1a;SAXReader 当解析到path指定的路径时&#xff0c;将调用参数handler指定的处理器。针对不同的节点可以添加多个handler实例。或者调用默认的Handler setDefaultHandler(ElementHandler handler); 2、接口ElementHandler onStart() 该方法在解析到元素的开始…

Visual Assist X 安装、使用 和 快捷键

Visual Assist 官网地址&#xff1a;https://www.wholetomato.com visual Assist 快捷键大全&#xff1a;https://blog.csdn.net/dddd0216/article/details/80082885 Visual Assist X的使用&#xff1a;https://jingyan.baidu.com/article/380abd0a4844111d90192c9a.html Vi…

Dom4j完整教程~通过xpath查找指定的节点

采用xpath查找需要引入jaxen-xx-xx.jar&#xff0c;否则会报java.lang.NoClassDefFoundError: org/jaxen/JaxenException异常。 List listdocument.selectNodes("/books/book/show"); xpath语法 1、选取节点 XPath 使用路径表达式在 XML 文档中选取节点&#xff0…

盘点丨毕业年薪34万,高校人工智能研究哪家强?

来源&#xff1a;亿欧网摘要&#xff1a;人才短缺已经成为了制约人工智能技术发展和应用落地的一大短板&#xff0c;为了弥补这一短板&#xff0c;加强人才培养&#xff0c;近日教育部发布了《高等学校人工智能创新行动计划》此前有报道显示&#xff0c;2017年AI工程师平均年薪…

第1章 Hello MFC

微软 MFC 官方文档&#xff1a;https://docs.microsoft.com/zh-cn/cpp/mfc/mfc-desktop-applications?viewvs-2019 MFC 层次结构图以及下载地址&#xff1a;https://docs.microsoft.com/zh-cn/cpp/mfc/hierarchy-chart?viewvs-2019 VC6.0/VS2005/VS2010/VS2012/VS2013/VS201…

navigator 对象

转载&#xff1a; http://www.itlearner.com/code/js_ref/brow1.htm 包含了正在使用的 Navigator 的版本信息。 客户端对象 实现版本 Navigator 2.0 Navigator 3.0: 添加了 mimeTypes 和 plugins 属性&#xff1b;添加了 javaEnabled 和 taintEnabled 方法。 Navigator 4.0: …

产业|MIR睿工业:2018年机器人市场分析报告

来源&#xff1a;Robot未来智能实验室是人工智能学家与科学院相关机构联合成立的人工智能&#xff0c;互联网和脑科学交叉研究机构。未来智能实验室的主要工作包括&#xff1a;建立AI智能系统智商评测体系&#xff0c;开展世界人工智能智商评测&#xff1b;开展互联网&#xff…

p1和p7签名的区别

前言: P1签名:即裸签名,签名值中只有签名信息. p7签名:即,签名中可以带有其他的附加信息,例如签名证书信息,签名原文信息,时间戳信息等. 所以要注意,不要p7的签名,用p1的方式来验签,这样是不对的.是错误的. 数字签名中,包含了两个过程: 1.对要签名的信息,用指定的hash算法,获取…

用 Python 和 werobot 框架开发公众号

From&#xff1a;用 Python 和 werobot 框架开发公众号&#xff1a;https://www.jianshu.com/p/a517746a900f WeRoBot 官方文档 &#xff1a;https://werobot.readthedocs.io/zh_CN/latest/ Github &#xff1a;https://github.com/offu/WeRoBot Python — WeRobot&#xff0…