设计和实现服务协定
WCF术语介绍
服务(Service):服务是一个构造,它公开一个或多个终结点,其中每个终结点都公开一个或多个服务操作。
终结点(EndPoint):终结点是用来发送或接收消息(或执行这两种操作)的构造。终结点包括一个定义消息可以发送到的目的地的位置(地址)、一个描述消息应如何发送的通信机制规范(绑定)以及对于可以在该位置发送或接收(或两者皆可)的一组消息的定义(服务协定)— 该定义还描述了可以发送何种消息。
应用程序终结点:一个终结点,由应用程序公开并对应于该应用程序实现的服务协定。
基础结构终结点:一个终结点,由基础结构公开,以便实现与服务协定无关的服务需要或提供的功能。 例如,服务可能拥有一个提供元数据信息的基础结构终结点。
地址(Adress):地址指定接收消息的位置。 地址以统一资源标识符 (URI) 的形式指定。 URI 架构部分指定用于到达该地址的传输机制,如 HTTP 和 TCP。 URI 的层次结构部分包含一个唯一的位置,其格式取决于传输机制。
绑定(Binding):绑定定义终结点与外界进行通信的方式。它由一组称为绑定元素的要素构造而成,这些元素“堆叠”在一起以形成通信基础结构。 绑定最起码应定义传输协议(如HTTP 或 TCP)和所使用的编码(如文本或二进制)。 绑定可以包含指定详细信息(例如,用于保护消息的安全机制或终结点所使用的消息模式)的绑定元素。
服务协定:服务协定将多个相关的操作联系在一起,组成单个功能单元。 协定可以定义服务级设置,如服务的命名空间、对应的回调协定以及其他此类设置。 在大多数情况下,协定是通过用您所选的编程语言创建一个接口并将 ServiceContractAttribute 属性应用于该接口来定义的。 通过实现该接口,可生成实际的服务代码。
操作协定:操作协定定义参数并返回操作的类型。 在创建定义服务协定的接口时,可以通过将 OperationContractAttribute 属性应用于协定中包含的每个方法定义来表示一个操作协定。 可以将操作建模为采用单个消息作为参数并返回单个消息,或者建模为采用一组类型作为参数并返回一个类型。 在后一种情况下,系统将确定需要为该操作交换的消息的格式。
宿主:服务必须承载于某个进程中。 “宿主”是控制服务的生存期的应用程序。 服务可以是自承载的,也可以由现有的宿主进程进行管理。
创建服务协定
类或接口都可以定义服务协定(但是建议使用接口,因为接口可以直接对服务协定建模)
服务协定接口具有托管接口的所有优点:
服务协定接口可以扩展任何数量的其他服务协定接口。
一个类可以通过实现服务协定接口来实现任意数量的服务协定。
可以通过更改接口实现来修改服务协定的实现,而让服务协定保持不变。 持不变。
可以通过实现旧接口和新接口来确定服务的版本。 老客户端连接到原始版本,而新客户端则可以连接到较新的版本
定义服务协定
在类或接口上使用ServiceContractAttribute属性标记
定义服务操作
在方法上使用OtiCttAttibt属性对其进行标记 – 在方法上使用OperationContractAttribute属性对其进行标记
参数和返回值
每个操作都有一个返回值和一个参数 即使它们为void 可以使用局部方法将对对象的引用从一个对象传递到另一个对象,但与局部方法不同的是,服务操作不会传递对对象的引用, 它们传递的只是对象的副本。
这是因为参数或返回值中使用的每个类型都必须是可序列化的,换言之,该类型的对象必须能够转换为字节流, 是可序列化的。
默认情况下,基元类型是可序列化的,.NET Framework 中的很多类型都是可序列化的
创建服务协定一:请求/响应
创建服务协定二:单向传输
创建服务协定三:双向传输
数据协定
数据协定:是服务协定的一部分用于描述您的服务操作交换的数据是服务协定的一部分,用于描述您的服务操作交换的数据。
一般使用DataContractAttribute和DataMemberAttribute属性对您的类型进行标记。
[DataContract] public class CompositeType { bool boolValue = true; string stringValue = "Hello "; [DataMember] public bool BoolValue { get { return boolValue; } set { boolValue = value; } } [DataMember] public string StringValue { get { return stringValue; } set { stringValue = value; } } }
数据协定是可选的样式协定:除非您显式应用数据协定属性,否则不会序列化任何类型或数据成员
数据协定与托管代码的访问范围无关:可以对私有数据成员进行序列 并将其发送到其他位置,以便可以公开访问它们
WCF处理用于启用操作功能的基础SOAP消息的定义并处理数据类型到消息正文的序列化和从消息正文进行的反序列化。 数据类型一旦序列化,您就无需在设计操作时考虑基础消息交换基础结构
可以使用其他序列化机制。 标准ISerializable, SerializableAttribute和IXmlSerializable 机制都可用于处理数据类型到基础SOAP消息序列化,这些消息可将数据类型从一个应用程序带到另一个应用程
引用方式传参
Out和Ref参数:由于out 和ref 参数都指示数据是从操作返回的,操作签名增加这2个关键字会使变更生效并返回
[ServiceContract] public interface IMyContract { [OperationContract] voidPopulateData(refCustomDataType data); }
保留修改和方法返回值无关,即便是VOID
如果操作是单向操作,则将在运行时引发InvalidOperationException 异常