Messsage是wcf信道层提供的一个类,在这个类中,数据被标识成一个xml infoset。当数据准备从客户端传输给服务端时,绑定里指定的信息编码协议将决定包含客户端所提供数据的Message对象以何种方式提交给服务。
当wcf服务接收到传输数据时,不管客户端是怎么样的编码格式,消息编码绑定元素会重新将它组装成一个Message对象,客户端发送的数据对象就会在Message对象中以XML InfoSet的形式表示。这个Message对象传送给Wcf的调度器(dispatcher)组件,它从xml infoset中抽取客户端的数据项,然后调用服务中实现了客户端请求的操作的方法,而这些数据项将作为方法的参数。
综上所述,即客户端发送给服务的数据会被序列化成xml,然后再服务端又会从xml反序列化成原始的数据。
wcf提供了两种xml序列化工具来完成上述任务。即System.xml.serialization.xmlserializer;System.runtime.serialization.datacontractserializer。其中,xmlSerializer为如何将数据表示成xml提供了精确的控制,默认将所有公有数据项序列化成xml;datacontractserializer只允许指定在xml中用来引用数据的命名空间和名称,以及数据项在xml里出现的顺序;天降datamember显示地指定哪些数据需要序列化。
服务端契约:
服务端契约实现:
客户端契约形式:
注意与服务端的差别
若服务版本的类型与客户端的类型被用来定义相互兼容(具有相同的命名空间和名称,而且每个版本契约里具有相同名称的成员都具有同样的类型)的数据契约。若客户端本本包括服务端版本没有的成员,可以在实现IExtensibledataobject接口。通过使用这个接口,类会另外分配空间,这样datacontractserializer可以用来存储、访问数据契约其他版本可能包含的成员字段。
服务端版本:
客户端版本:
当需要使用参数类型的子类型的实例作为输入来访问服务时,就必须添加ServiceKnownType特性,即应避免使用继承关系作为数据契约升级版本的方法。如果定义的是父类型参数而接收的是子类型,除非修改代码为预测到的子类型添加ServiceKnownType,否则子类型的序列化将会失败。
注意在上文契约中的特性: