WCF技术剖析之十二

数据契约(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,以便于您获取更多的相关知识。

时间: 2024-10-24 22:43:08

WCF技术剖析之十二的相关文章

WCF技术剖析之十二:数据契约(Data Contract)和数据契约序列化器(DataContractSerializer)

原文:WCF技术剖析之十二:数据契约(Data Contract)和数据契约序列化器(DataContractSerializer) [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制的节目视频(苏州话)]]大部分的系统都是以数据为中心的(Data Central),功能的实现表现在对相关数据的正确处理.而数据本身,是有效信息的载体,在不同的环境具有不同的表示.一个分布式的互联系统关注于数据的交换,而数据正常交换的根本前提是参与数据交换的双方对于数据结

WCF技术剖析之三十二:一步步创建一个完整的分布式事务应用

在完成了对于WCF事务编程(<上篇>.<中篇>.<下篇>)的介绍后,本篇文章将提供一个完整的分布式事务的WCF服务应用,通过本例,读者不仅仅会了解到如何编程实现事务型服务,还会获得其他相关的知识,比如DTC和AS-AT的配置等.本例还是沿用贯通本章的应用场景:银行转帐.我们将会创建一个BankingService服务,并将其中的转帐操作定义成事务型操作.我们先从物理部署的角度来了解一下BankingService服务,以及需要实现怎样的分布式事务. 一.从部署的角度看分

WCF技术剖析之十五:数据契约代理(DataContractSurrogate)在序列化中的作用

原文:WCF技术剖析之十五:数据契约代理(DataContractSurrogate)在序列化中的作用 [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制的节目视频(苏州话)]]如果一个类型,不一定是数据契约,和给定的数据契约具有很大的差异,而我们要将该类型的对象序列化成基于数据契约对应的XML.反之,对于一段给定的基于数据契约的XML,要通过反序列化生成该类型的对象,我们该如何实现这样的场景? 比如下面定义了两个类型Contact和Customer,

WCF技术剖析之十八:消息契约(Message Contract)和基于消息契约的序列化

在本篇文章中,我们将讨论WCF四大契约(服务契约.数据契约.消息契约和错误契约)之一的消息契约(Message Contract).服务契约关注于对服务操作的描述,数据契约关注于对于数据结构和格式的描述,而消息契约关注的是类型成员与消息元素的匹配关系. 我们知道只有可序列化的对象才能通过服务调用在客户端和服务端之间进行传递.到目前为止,我们知道的可序列化类型有两种:一种是应用了System.SerializableAttribute特性或者实现了System.Runtime.Serializat

WCF技术剖析之三十:一个很有用的WCF调用编程技巧[下篇]

在<上篇>中,我通过使用Delegate的方式解决了服务调用过程中的异常处理以及对服务代理的关闭.对于<WCF技术剖析(卷1)>的读者,应该会知道在第7章中我通过类似于AOP的方式解决了相似的问题,现在我们来讨论这个解决方案. 通过<服务代理不能得到及时关闭会有什么后果?>的介绍,我们知道了及时关闭服务代理的重要意义,并且给出了正确的编程方式.如果严格按照上面的编程方式,就意味着对于每一个服务调用,都要使用相同的代码进行异常处理和关闭或中断服务代理对象.按照我个人的观点

WCF技术剖析之三十:一个很有用的WCF调用编程技巧[上篇]

在进行基于会话信道的WCF服务调用中,由于受到并发信道数量的限制,我们需要及时的关闭信道:当遇到某些异常,我们需要强行中止(Abort)信道,相关的原理,可以参考我的文章<服务代理不能得到及时关闭会有什么后果?>.在真正的企业级开发中,正如我们一般不会让开发人员手工控制数据库连接的开启和关闭一样,我们一般也不会让开发人员手工去创建.开启.中止和关闭信道,这些工作是框架应该完成的操作.这篇文章,我们就来介绍如果通过一些编程技巧,让开发者能够无视"信道"的存在,像调用一个普通对

WCF技术剖析之十九:深度剖析消息编码(Encoding)实现(下篇)

通过上篇的介绍,我们知道了WCF所有与编码与解码相关的功能都实现在相应的System.Xml.XmlDictionaryWriter和System.Xml.XmlDictionaryReader中.但是在真正的WCF处理框架中,却并不直接使用XmlDictioanryWriter和XmlDictionaryReader对象,而通过相应的消息编码器(System.ServiceModel.Channels.MessageEncoder)对其进行进一步封装,专门用于消息的编码和解码. 一.消息编码器

WCF技术剖析之十六:数据契约的等效性和版本控制

数据契约是对用于交换的数据结构的描述,是数据序列化和反序列化的依据.在一个WCF应用中,客户端和服务端必须通过等效的数据契约方能进行有效的数据交换.随着时间的推移,不可避免地,我们会面临着数据契约版本的变化,比如数据成员的添加和删除.成员名称或者命名空间的修正等,如何避免数据契约这种版本的变化对客户端现有程序造成影响,就是本节着重要讨论的问题. 一.数据契约的等效性 数据契约就是采用一种厂商中立.平台无关的形式(XSD)定义了数据的结构,而WCF通过DataContractAttribute和D

WCF技术剖析之十八:消息契约(Message Contract)和基于消息契约的序列化

在本篇文章中,我们将讨论WCF四大契约(服务契约.数据契约.消息契约和错误契约)之一的消息契约(Message Contract).服务契约关注于对服务操作的描述,数据契约关注于对于数据结构和格式的描述,而消息契约关注的是类型成员与消息元素的匹配关系. 我们知道只有可序列化的对象才能通过服务调用在客户端和服务端之间进行传递.到目前为止,我们知道的可序列化类型有两种:一种是应用了System.SerializableAttribute特性或者实现了System.Runtime.Serializat