分类: 系统运维
2008-12-04 20:15:31
数据序列化:
WCF作为分布式开发技术的一种,为了实现分布式应用程序之间互相传递消息,需要事先定制好数据交换规则,即契约。这些规则正是交换数据的双方能彼此理解对方的依据。
服务契约是最基本也是最重要的一种契约。而在服务契约中,为了传递复杂的数据类型(比如对象),需要实现复杂类型的序列化。
WCF提供的复杂类型的序列化主要有三种方式:可序列化类型;数据契约;IXmlSerializable。
可序列化类型(SerializableAttribute)。大部分CLR类型都可以使用此序列化类型,使用方法是在代码元素之前使用Serializable特性。可序列化类型的缺点有:无论各成员元素的可访问性如何,所有域都被序列化;无法对命名规范或者数据类型进行控制。
为了解决以上问题,使用数据契约是一个方法。数据契约用于自定义数据结构的契约,它分为两种:DataContract和DataMemberContract。通过这两种标记指示 WCF此复杂类型能够被序列化并传输,而DataMember只能用在类或者结构的属性(Property)或者字段(Field)上,指示WCF该属性或者字段能够被序列化传输。
IXmlSerializable序列化方式。在理想的WCF世界之中,使用Contract-First的开发方式:在开发的时候,先定义各种契约,将所要提供的服务暴露在这些服务契约之中。但是在实际情况中,这种方式有时难以实现,例如对象不可序列化或是序列化不正确。为了解决这些问题,就需要开发人员自己实现序列化器。在WCF中,开发人员可使用IXmlSerializable类型实现序列化器,通过这个序列化器序列化特定对象。使用IXmlSerializable时,开发人员需要自己处理XML与对象之间的映射关系。
已知类型(KnownType):
为了实现WCF的面向服务功能,一些面向对象的特性例如继承和多态被丢失了。所以才有了已知类型来弥补这些特性。
已知类型(Known types)允许在服务契约中使用多态的行为。通过在声明契约属性时声明已知类型,使得客户端在使用派生自基类(定义了数据契约的)的子类,从而实现多态行为。而且这些子类也需要进行数据序列化(定义数据契约),否则,例如在客户端使用服务时如果使用未声明的子类到基类的转换时,WCF将抛出异常。
已知类型在使用时,可以相关到三个地方:(1)基本类型自身;(2)特定操作;(3)整个服务契约。
已知类型可采用属性声明或者配置的方式来实现。
(1)通过在属性中声明的方式实现已知类型。
1、相关到基本类型自身,在数据契约中声明。例如:
[DataContract(Namespace"")]
[KnownType(typeof(GigInfo))]
[KnownType(typeof(PhotoLink))]
[KnownType(typeof(MP3Link))]
public class LinkItem : IExtensibleDataObject{……}
//LinkItem里面的成员方法可以使用G
2、相关到特定操作,在具体操作(方法)的属性中声明已知类型,实现多态性的一种严格的限制。例如:
[OperationContract]
[ServiceKnownType(typeof(GigInfo))]
LinkItem GetGig();//同上面的方式相比,这个方法里只能使用GigIngo数据类型
3、相关到整个服务契约,例如在提供服务的接口中声明已知类型。例如:
[ServiceContract(Name = "GigManagerServiceContract", Namespace = "", SessionMode = SessionMode.Required)]
[ServiceKnownType(typeof(GigInfo))]
public interface IGigManagerService{……}
(2)非编码的方式,即配置的方式实现。例如在拿不到服务的代码,也拿不到基类的代码,而希望为服务添加新的功能的情况下,就可以通过在主机进程(Host)中修改配置文件的方式实现。例如: