(四)、WCF契约编程

 

  1. 契约类型:
  2. 服务契约(Service Contract)定义了客户端执行的服务操作
  3. 数据契约(Data Contract)定义了与服务交互的数据类型
  4. 消息契约(Message Contract) 允许服务直接与消息交换
  5. 错误契约(Fault Contract)定义了服务抛出的错误

2. 服务契约:

  1. 2.1  服务契约和WSDL: 服务契约和WSDL转化

    ServiceContract --> wsdl:service

    OperationContract --> wsdl:operation

    2.2 服务契约的重载问题

    WCF不能使用重载,但使用OperationContractName可以解决。

     

    2.3 定义请求-响应操作

    同步和异步操作。大部分绑定都是请求响应操作。只有使用MSMQ协议和P2P协议不支持请求——响应操作

    2.4 定义单程操作(One Way)不需要服务端给出响应

      

    2.5 定义双程操作:使得服务端可以回调客户端操作,而不需要在客户端实现,寄宿新的服务契约

    2.5.1  定义:允许客户端向服务端发出调用,而服务端也可向客户端发出调用,所有也称为回调操作

    2.5.2 双程操作的服务端设置:其核心内容是定义回调契约,在WCF中使用ServiceContractCallbackContract属性定义一个回调契约。

    2.5.3 双程操作的客户端设置:需要公开回调总结点以供服务端进行回调。

    2.5.4 双程操作的死锁问题

    回调动作会引发死锁:

  2. 默认情况下,服务端被配置为单线程访问。当 服务类型执行时,该对象被锁。
  3. 服务回调客户端操作时,当前线程被阻止,但锁未被释放。
  4. 当回调操作完成时,客户端发送返回消息,这时候需要争用服务端服务对象的锁。
  5. 这时候服务对象仍处于等待中,并且占据锁,死锁产生。
  6. 三种解决方法:

  7. 设置回调操作为单程操作,这样客户端的回调操作完成后,不需要发送返回信息。也就不会产生死锁。
  8. 设置服务的并发行为为多线程。这样多个线程访问对象,而不产生争用情况。但由于设置了多线程,服务的实现必须考虑特殊资源的同步问题。
  9. 设置服务的并发行为为可重入。这种情况下,服务对象仍只允许单线程访问。但服务端回调客户端操作时,WCF释放对象锁,这样就不会产生争用(不理解)
  10. 2.5.5 实例:

     

    2.6  WCF 中事件的实现。 WCF中,事件的实现机制要依靠双程操作。一般而言,客户端通过调用服务端的方法来订阅时间,而服务端通过回调来触发事件,为了保存客户端订阅事件的回调引用,可以用委托链来保存每个事件的回调引用。

3.数据契约

 

  • 类型名、成员名、成员类型:可以使用Name属性定义类型在XSD中的别名。
  • 序列化顺序相等:

 

  1. 3.1 数据契约和XSD

    数据契约需要转化成跨平台的数据定义,所使用的就是XSD

    3.2 使用DataContract特性定义数据契约

    使用DataContract特性而不使用传统的Serializable特性的目的之一,就是精确的指定哪些成员需要在服务器中实现。DataContractDataMember不受publicprivate可访问修饰符的限制。

    3.3 数据契约的继承

    WCF支持数据类型的继承,但父类和子类必须都属于数据契约。

     

    3.4 已知类型的定义:就是强行的将数据类型放入到服务的元数据中。

    3.4.1 使用KnowType特性在数据类型上声明,用于声明数据契约所知的类型。通常情况下指的是该类型的所有被服务使用到的子类。

    3.4.2 使用ServiceKnownType特性定义已知类型。和KnownType不同的是,该特性被声明在服务契约或者特定的操作契约上。这样声明的范围更小,更灵活。

       3.4.3 在接口上使用已知类型

    3.5 数据契约的等效性

    所谓等效的数据契约是指数据契约具有相同的传输表述形式。主要有以下两点要素:

    A 如果是继承,则基类数据成员排在第一位

    B 排在下一位的当前类型的数据成员(按字母顺序)

    C 设置DataMemberAttribute特性的Order属性的任何成员

    3.6 数据契约的版本控制

    3.6.1 新增成员,WCF对新增成员的策略是丢失新增字段。

    3.6.2 缺失成员, WCF对缺失的成员赋值为0null

    3.7 定义必须的数据成员。

    用DataMember的特性IsRequied属性定义必须的数据成员。

    3.8 数据默认值的发生

    DataMemberEmitDefaultValue属性设为false,避免发生默认值传送

    3.9 数组和集合的处理

    3.9.1 对数组作为一种类型处理

    3.9.2 集合 定义了CollectionDataContract 特性

4. 消息契约

  1. 如果想要定制SOAP消息的HeadBody内容,就需要用到消息契约

    4.1 基本概念

    消息 契约给予程序员直接访问SOAP消息的HeadBody部分的能力

    4.2 强类型消息

    使用MessageContract特性来声明,一旦声明了MessageContract,类型可以作为SOAP消息发送或接受

     

    4.3 弱类型消息

    利用Message作为消息契约

5.错误处理和错误契约

  1. 5.1 SOAP消息的错误处理

    异常被放在SOAP body里的Fault节点上。

    5.2 服务端未捕获的异常: FalutException SOAPfault节点直接对应

    5.3 包含详细信息的异常:解决未捕获的异常丢失的问题就是使用ServiceDebugBehaviorIncludeExceptionDetailInFaults属性

    5.4 捕获服务异常,如果未捕获异常,将会导通信结束

    5.5 FaultCodeFaultReason的使用

    5.5.1 FaultCode的设置,分为三类:

  2. Sender
  3. Receiver
  4. 自定义
  5. 5.5.2 FalutReason的设置

    5.6 使用错误契约和FaultException<T>

     

    代码示例下载

     

     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值