数据契约(Data Contract)和数据契约序列化器(DataContractSerializer)
大部分的系统都是以数据为中心的(Data Central),功能的实现表现在对相关数据的正确处理。而数据本身,是有效信息的载体,在不同的环境具有不同的表示。一个分布式的互联系统关注于数据的交换,而数据正常交换的根本前提是参与数据交换的双方对于数据结构的一致性理解。这就为数据的表现提出了要求,为了保证处于不同平台、不同厂商的应用能够正常地进行数据交换,交换的数据必须采用一种大家都能够理解的展现方式。在这方面,XML无疑是最好的选择。所以WCF下的序列化(Serialization)解决的就是如何将数据从对象的表现形式转变成XML表现形式,以确保数据的正常交换。从本章起,我将讲述WCF序列化的本质,首先从从数据契约谈起。
一、数据契约
一个正常的服务调用要求客户端和服务端对服务操作有一致的理解,WCF通过服务契约对服务操作进行抽象,以一种与平台无关的,能够被不同的厂商理解的方式对服务进行描述。同理,客户端和服务端进行有效的数据交换,同样要求交换双方对交换数据的结构达成共识,WCF通过数据契约来对交换的数据进行描述。与数据契约的定义相匹配,WCF采用新的序列化器——数据契约序列化器(DataContractSerializer)进行基于数据契约的序列化于反序列化操作。
同服务契约类似,WCF采用了基于特性(Attribute)的数据契约定义方式。基于数据契约的自定义特性主要包含以下两个:DataContractAttribute和DataMemberAttribute,接下来我们将讨论这两个重要的自定义特性。
DataContractAttribute和DataMemberAttribute
WCF通过应用DataContractAttribute特性将其目标类型定义成一个数据契约,下面是DataContractAttribute的定义。从AttributeUsage的定义来看,DataContractAttribute只能用于枚举、类和结构体,而不能用于接口;DataContractAttribute是不可以被继承的,也就是说当一个类型继承了一个应用了DataContractAttribute特性类型,自身也只有显式地应用DataContractAttribute特性才能成为数据契约;一个类型上只能应用唯一一个DataContractAttribute特性。
1: [AttributeUsage(AttributeTargets.Enum | AttributeTargets.Struct | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] 2: public sealed class DataContractAttribute : Attribute 3: { 4: public bool IsReference { get; set; } 5: public string Name { get; set; } 6: public string Namespace { get; set; } 7: }
DataContractAttribute仅仅包含3个属性成员。其中Name和Namespace表示数据契约的名称和命名空间;IsReference表示在进行序列化的时候是否保持对象现有的引用结构。比如说,一个对象的两个属性同时引用一个对象,那么有两个序列化方式,一种是在序列化后的XML仍然保留这种引用结构,另一种是将两个属性的值序列化成两份独立的具有相同内容的XML。
对于服务契约来说,我们在一个接口或者类上面应用的ServiceContractAttribute将其定义成服务契约后,并不意味着该接口或者类中的每一个方法成员都是服务操作,而是通过OperationContractAttribute显式地将相应的方法定义成服务操作。与之类似,数据契约也采用这种显式声明的机制。对于应用了DataContractAttribute特性的类型,只有应用了DataMemberAttribute特性的字段或者属性成员才能成为数据契约的数据成员。DataMemberAttribute特性的定义如下所示。
1: [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = false, AllowMultiple = false)] 2: public sealed class DataMemberAttribute : Attribute 3: { 4: public DataMemberAttribute(); 5: 6: public bool EmitDefaultValue { get; set; } 7: public bool IsRequired { get; set; } 8: public string Name { get; set; } 9: public int Order { get; set; } 10: }
下面的列表列出了DataMemberAttribute的4个属性所表述的含义。
Name:数据成员的名称,默认为字段或者属性的名称;
Order:相应的数据成员在最终序列化后的XML出现的位置,Order值越小越靠前,默认值为-1;
IsRequired:表明属性成员是否是必须的成员,默认值为false,表明该成员是可以缺省的;
EmitDefaultValue:表明在数据成员的值等于默认值的情况下,是否还需要将其序列化到最终的XML中,默认值为true,表示默认值会参与序列化。
注: 数据契约和数据成员只和是否应用了DataContractAttribute和DataMemberAttribute有关,与类型和成员的存取限制修饰符(public,internal、protected,private等)无关。也就是说,应用了DataMemberAttribute的私有字段或属性成员也是数据契约的数据成员。
二、数据契约序列化器(DataContractSerializer)
在WCF中,数据契约的定义是为序列化和反序列化服务的。WCF采用数据契约序列化器(DataContractSerializer)作为默认的序列化器。接下来我们着重谈谈DataContractSerializer和基于DataContractSerializer采用的序列化规则。先来看看DataContractSerializer的定义。
1: public sealed class DataContractSerializer : XmlObjectSerializer 2: { 3: //其他成员 4: public DataContractSerializer(Type type); 5: //其他构造函数 6: 7: public override object ReadObject(XmlReader reader); 8: public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName); 9: public override object ReadObject(XmlReader reader, bool verifyObjectName); 10: public override void WriteObject(XmlWriter writer, object graph); 11: 12: public IDataContractSurrogate DataContractSurrogate { get; } 13: public bool IgnoreExtensionDataObject { get; } 14: public ReadOnlyCollection<Type> KnownTypes { get; } 15: public int MaxItemsInObjectGraph { get; } 16: public bool PreserveObjectReferences { get; } 17: }
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索数据
, 服务
, public
, 数据契约
, 特性
, 一个
成员
wcf技术剖析、wcf技术剖析 卷2 pdf、wcf技术剖析 pdf、wcf技术剖析 下载、wcf技术剖析 卷2,以便于您获取更多的相关知识。