服务契约定义了远程访问对象和可供调用的方法,数据契约则是服务端和客户端之间要传送的自定义数据类型。

一旦声明一个类型为DataContract,那么该类型就可以被序列化在服务端和客户端之间传送,如下所示。

[DataContract]

public class UserInfo

{

//….

}

只有声明为DataContract的类型的对象可以被传送,且只有成员属性会被传递,成员方法不会被传递。WCF对声明为DataContract的类型提供更加细节的控制,可以把一个成员排除在序列化范围以外,也就是说,客户端程序不会获得被排除在外的成员的任何信息,包括定义和数据。默认情况下,所有的成员属性都被排除在外,因此需要把每一个要传送的成员声明为DataMember,如下所示。

[DataContract]

public class UserInfo

{

[DataMember]

public string UserName

{

get;

set;

}

[DataMember]

public int Age

{

get;

set;

}

[DataMember]

public string Location

{

get;

set;

}

public string Zodiac

{

get;

set;

}

}

上面这段代码把UserInfo类声明为DataContract,将UserName、Age、Location这3个属性声明为DataMember(数据成员)。Zodiac成员没有被声明为DataMember,因此在交换数据时,不会传输Zodiac的任何信息。

DataContract也支持Name/Namespace属性,如同ServiceContract,Name和Namespace可以自定义名称和命名空间,客户端将使用自定义的名称和命名空间对DataContract类型进行访问。

声明为DataMember的成员也可以自定义客户端可见的名称,例如:

[DataMember(Name="Name")]

public string UserName

{

get;

set;

}

[DataMember(Name="Age")]

public int UserAge

{

get;

set;

}

除了Name和Namespace以外,DataMember还有以下参数,它们的含义分别如下。

(1)IsRequired:值为true时,要求序列化引擎检查对象是否存在该值;若无,则会有异常抛出。

(2)Order:bool类型值,值为true时,序列化和反序列化过程将会按成员定义的顺序进行,这对依赖于成员位置的反序列化过程无比重要。

(3)EmitDefaultvalue:为成员属性设置一个默认值。

一般情况下,将类型声明为DataContract就可以满足传送的需求了,不过特殊情况是难以避免的,这时就需要对要传送的SOAP消息进行更加精确的控制,MessageContract可以满足这种需求。

把一个类型声明为MessageContract,意味着它可以被序列化为SOAP消息,可以声明类型的成员为SOAP消息的各个部分,如Header、Body等,如下所示。

[MessageContract]

public class UserMessage

{

private string user = String.Empty;

private string authKey = String.Empty;

[MessageBodyMember(

Name = "UserName",

Namespace = "http://www.wcf.com")]

public string User

{

get { return user; }

set { user = value; }

}

[MessageHeader(

Name = "AuthKey",

Namespace = "http://www.wcf.com",

MustUnderstand = true

)]

public string AuthKey

{

get { return authKey; }

set { this.authKey = value; }

}

}

User成员被声明为MessageBody(消息体)的一个成员,AuthKey被声明为消息头(MessageHeader)的一个成员。这个类将可以生成如下的SOAP消息。

<s:Envelope>

<s:Header>

<a:Action s:mustUnderstand="1">http://UserMessage/Action</a:Action>

<h:AuthKey s:mustUnderstand="1" xmlns:h="http://www.wcf.com">xxxx</h:AuthKey>

</s:Header>

<s:Body>

<UserMessage xmlns="Microsoft.WCF.Documentation">

<User xmlns="http://www.wcf.com">abcd</User>

</UserMessage>

</s:Body>

</s:Envelope>

MessageHeader中,MustUnderstand参数表示读取该头的程序必须能够识别头的内容,否则不能继续处理。Name/Namespace的作用与前面的元素相同。另有Relay参数,若为true,头的内容被接收到以后会在响应消息中回发给消息发送端。

最新文章

  1. iOS 开发:CoCoapods的使用和安装
  2. 自定义shape文件
  3. 【POJ】1284 Primitive Roots
  4. Naive Bayes理论与实践
  5. chem02-- ajax登录
  6. mysql innodb 引擎
  7. 关于.ToList(): LINQ to Entities does not recognize the method ‘xxx’ method, and this method cannot be translated into a store expression.
  8. [Falcor] Indroduce to Model
  9. 编辑一个类库项目 即*.csproj这个文件的正确方式
  10. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(20)-多条件模糊查询和回收站还原的实现
  11. 搞java的都土鳖
  12. (二)SpringBoot基础篇- 静态资源的访问及Thymeleaf模板引擎的使用
  13. 五分钟读懂UML类图(转)
  14. 网络协议 9 - TCP协议(下):聪明反被聪明误
  15. 前端js收藏
  16. J2EE [web] 403.500.404页面配置
  17. ajax上传文件以及实现上传进度条(转载)
  18. anaconda里面安装tensorflow
  19. Jdk 和 Tomcat的 安装。
  20. 亚马逊API的使用

热门文章

  1. [BZOJ1559]密码 AC自动机+状压
  2. MT【155】单调有界必有极限
  3. Storm入门到精通(四)---本地实例Demo
  4. 【BZOJ2813】奇妙的Fibonacci
  5. maven管理工具
  6. NAT ------ 内网的主机如何通过路由器与外网的主机通信
  7. Tomcat权威指南-读书摘要系列4
  8. python 中的os模块
  9. 数据分析与展示---Numpy数据存取与函数
  10. Shell记录-Shell脚本基础(三)