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中,并没有限制客户端是什么平台,事实上,连服务端也是。只有契约没有变。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值