WCF学习笔记--设计服务协定

一、创建服务协定
服务--一组操作。
在WCF应用程序中,通过创建一个方法并使用 OperationContractAttribute属性对其进行标记来定义操作。若要创建服务协定,需要将操作组合到一起。在使用ServiceContractAttribute属性标记的接口中声明这些操作,或在同样使用ServiceContractAttribute属性标记的类中定义它们。
任何不具有OperationContractAttribute属性的方法都不是服务操作,并且不能公开给WCF服务的客户端使用。

二、类和接口
类和接口都表示一组功能,不过建议使用接口(接口可以直接对服务协定建模)。
服务协定接口具有托管接口的所有优点:

  • 服务协定接口可以扩展任何数量的其他服务协定接口
  • 一个类可以通过实现服务协定接口来实现任意数量的服务协定
  • 通过更改接口实现来修改服务协定的实现,而让服务协定保持不变。
  • 通过实现旧接口和新接口来确定服务的版本。老客户端连接到原始版本,而新客户端则可以连接到较新的版本
  • 注:从服务协定接口中继承时,不能重写操作属性,例如名称或命名空间。如果试图执行该操作,应在当前服务协定中创建新操作。

可以使用类来定义服务,并且实现该协定。类上标记ServiceContractAttribute,类中的方法标记OperationContractAttribute来创建服务,优点--快速且简便,缺点--托管类不支持多个继承、一次只能实现一个服务协定、更改类或方法的签名都将修改服务的公开协定。

三、参数和返回值
每个操作都有一个返回值和一个参数,即使它们都为void。服务操作不会传递对对象的引用而是传递对象的副本,这与局部方法传递对对象的引用有区别。
服务操作传递对象的副本是因为参数或者返回值中使用的每个类型都是必须是可被序列化的。基元类型都是可序列化的。

四、数据协定
面向服务的应用程序是为Microsoft平台与非Microsoft平台上的最大可能的客户端应用程序进行交互操作。因此建议您使用DataContractAttribute和DataMemberAttribute属性对您的类型进行标记,以创建数据协定。
数据协定是服务协定的一部分,用于描述您的服务操作交换的数据。数据协定是可选的样式协定:除非您显示应用数据协定属性,否则不会序列化任何类型或数据成员。数据协定与托管代码的访问范围无关:可以对似有数据成员进行序列化并将其发送到其他位置,以便可以公开访问它们。只要数据类型可序列化,你就无需再设计操作时考虑基础信息交互基础结构。
您也可以使用其他序列化机制,如ISerializable、SerializableAttribe和IXmlSerializable机制都可以用于处理数据类型到基础SOAP消息的序列化,这些消息可以讲数据类型从一个应用程序带到另一应用程序。
如果数据类型要求特殊的支持,则可以使用更多的序列化策略。

五、参数和返回值映射到消息交换
WCF编程模型中支持三种模式:请求/答复、单向和双工消息模式。
1)请求/答复
  通过请求/答复模式,请求发送方将接受与请求相关的答复。这是默认的MEP(基础交换模式),它即支持传入操作(一个或多个参数传入到该操作),也支持返回操作(该操作将一个或多个输出值传回给调用方)。    

[OperationContractAttribute]
string Hello(string greeting)
//即先接受一个字符创,再返回一个字符串
[OperationContractAttribute]
void Hello(string greeting)
//除非指定其他的基础消息模式。即便服务操作返回void,也属于请求/答复消息交换
//如果执行操作需要很长的时间,该实例会降低客户端性能和响应能力
//该实例的优势在于响应消息中可返回SOAP错误,这表明可能在通信或处理中发生了一些与服务有关的错误状况。

 2) 单向
  WCF服务应用程序的客户端不必等待操作完成,并且不处理SOAP错误。
  单向操作时客户端调用操作并在WCF将消息写入网络后继续进行处理的操作
  支持从客户端到服务应用程序的类似于事件的行为

[OperationContractAttribute(IsOneWay=true)]
void Hello(string greeting);
//为返回void的操作指定单向消息交换

 3)双工
  无论使用单向消息发送还是请求/答复消息发送方式,服务和客户端均能够独立地向对方发送消息。
  若要设计双工协定,还必须设计回调协定,并且该回调协定的类型分配给标记服务协定的ServiceContractAttribute特性的CallbackContract属性
  若要实现双工模式,你必须创建第二个接口,该接口包含在客户端调用的方法声明

六、Out和Ref参数
大部分情况下,您可以使用in、out和ref参数,out和ref参数都都是指示数据是从操作返回,如下面的实例

[ServiceContractAttribue]
public interface IMyContract
{
    [OperationContractAttribute]
    public void Population(ref CustomDataType data);   
}

只用当用于声明操作的方法返回void时,才能使用NetMsmqBinding绑定与客户端通信;不能有任何输出值,无论它是返回值、ref、还是out参数。
使用out或ref参数要求操作具有基础响应消息,才能将以修改的对象传回。如果操作时单向操作,则将在运行时引发InvalidOperationExecption异常。

七、指定协定上的消息保护级别设计协定时,还必须确定实现您的协定的服务的消息保护级别。大部分情况下,系统提供的绑定应用的事消息级别的安全,除非绑定将安全关闭(系统提供的绑定将System.ServiceMode.SecurityMode设置为System.ServiceMode.SecurityMode.Noe)时则不必确定绑定的消息保护级别。
保护级别是一个值,指定支持服务的消息(或消息部分)是进行签名、签名并加密,还是未经签名或者加密即发送。
可以在多个范围内设置保护级别:服务级别、针对特定操作、针对该操作内的消息或消息部分。该范围可覆盖。

[ServiceContract]
public interface ISampleService
{
    [OperationContractAttribute]
    public string GetString();

    [OperationContractAttribute]
    public int GetInt();   
}
//不会在协定上设置ProtectionLevel或ProtectionLevel属性

[ServiceContract]
public interface IExplicitProtectionLevelSampleService
{
   //加密并签名(默认)
[OperationContractAttribute] public string GetString(); //未加密并且未签名文本(纯文本) [OperationContractAttribute(ProtectionLevel=ProtectionLevel.None)] public int GetInt(); //将在一条已加密且签名的消息中返回 [OperationContractAttribute(ProtectionLevel=ProtectionLevel.EncryptAndSign)] public int GetGuid(); }

 八、其他操作签名要求
某些应用程序功能要求特定种类的操作签名。例如,NetMsmqBinding绑定支持持久性服务和客户端,即应用程序可以在通信期间重新启动,并在其停止的位置处拾取,不会遗漏任何消息。
另一个示例是在操作中使用Stream类型。由于Stream参数包括整个消息正文,如果输入或输出(也就是ref 参数、out 参数或返回值)的类型为Stream,则它必须是在操作中指定的唯一输入或输出。此外,参数或返回类型必须是Stream, System.Xml.Serialization.IXmlSerializable。

九、名称、命名空间和模糊处理

 

原文地址(MSDN):http://msdn.microsoft.com/zh-cn/library/ms731835(v=vs.100).aspx

posted @ 2013-03-06 22:30  lazysun  阅读(336)  评论(0)    收藏  举报