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

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

一、数据契约的等效性

数据契约就是采用一种厂商中立、平台无关的形式(XSD)定义了数据的结构,而WCF通过DataContractAttribute和DataMemberAttribute旨在给相应的类型加上一些元数据,帮助DataContractSerializer将相应类型的对象序列化成具有我们希望结构的XML。在客户端,WCF的服务调用并不完全依赖于某个具体的类型,客户端如果具有与服务端完全相同的数据契约类型定义,固然最好。如果客户端现有的数据契约类型与发布出来数据契约具有一些差异,我们仍然可以通过DataContractAttribute和DataMemberAttribute这两个特性使该数据契约与之等效。

简言之,如果承载相同数据的两个不同数据契约类型对象最终能够序列化出相同的XML,那么这两个数据契约就可以看成是等效的数据契约。等效的数据契约具有相同的契约名称、命名空间和数据成员,同时要求数据成员出现的先后次序一致。比如,下面两种形式的数据契约定义,虽然它们的类型和成员命名不一样,甚至对应成员在各自类型中定义的次序都不一样,但是由于合理使用了DataContractAttribute和DataMemberAttribute这两个特性,确保了它们的对象最终序列化后具有相同的XML结构,所以它们是两个等效的数据契约。

 1: [DataContract(Namespace = "http://www.artech.com/")] 2: public class Customer 3: { 4: [DataMember(Order=1)] 5: public string FirstName 6: {get;set;} 7: 8: [DataMember(Order = 2)] 9: public string LastName 10: { get; set; } 11: 12: [DataMember(Order = 3)] 13: public string Gender 14: { get; set; } 15: } 1: [DataContract(Name = "Customer", Namespace = "http://www.artech.com/")] 2: public class Contact 3: { 4: [DataMember(Name = "LastName", Order = 2)] 5: public string Surname 6: { get; set; } 7: 8: [DataMember(Name = "FirstName", Order = 1)] 9: public string Name 10: { get; set; } 11: 12: [DataMember(Name = "Gender", Order = 3)] 13: public string Sex 14: { get; set; } 15: }

数据契约版本的差异最主要的表现形式是数据成员的添加和删除。如何保证在数据契约中添加一个新的数据成员,或者是从数据契约中删除一个现有的数据成员的情况下,还能保证现有客户端的正常服务调用(对于服务提供者),或者对现有服务的正常调用(针对服务消费者),这是数据契约版本控制需要解决的问题。

二、数据成员的添加

先来谈谈添加数据成员的问题,如下面的代码所示,在现有数据契约(CustomerV1)基础上,在服务端添加了一个新的数据成员: Address。但是客户端依然通过数据契约CustomerV1进行服务调用。那么,客户端按照CustomerV1的定义对于Customer对象进行序列化,服务端则按照CustomerV2的定义对接收的XML进行反序列化,会发现缺少Address成员。那么在这种数据成员缺失的情况下,DataContractSerializer又会表现出怎样的序列化与反序列化行为呢?

 1: [DataContract(Name = "Customer", Namespace = "http://www.artech.com")] 2: public class CustomerV1 3: { 4: [DataMember] 5: public string Name 6: { get; set; } 7: 8: [DataMember] 9: public string PhoneNo 10: { get; set; } 11: } 1: [DataContract(Name = "Customer", Namespace = "http://www.artech.com")] 2: public class CustomerV2 3: { 4: [DataMember] 5: public string Name 6: { get; set; } 7: 8: [DataMember] 9: public string PhoneNo 10: { get; set; } 11: 12: [DataMember] 13: public string Address 14: { get; set; } 15: }

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索string
, 数据
, datamember
, 服务
, public
, 数据契约
, 9+ in7 + 成员数据
成员
,以便于您获取更多的相关知识。

时间: 2024-10-28 16:38:44

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

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

如果一个类型,不一定是数据契约,和给定的数据契约具有很大的差异,而我们要将该类型的对象序列化成基于数据契约对应的XML.反之,对于一段给定的基于数据契约的XML,要通过反序列化生成该类型的对象,我们该如何实现这样的场景? 比如下面定义了两个类型Contact和Customer,其中Customer是数据契约,Contact的Sex属性相当于Customer的Gender属性,而Contact的FullName可以看成是Customer的FirstName和LastName的组合.现在我们要做的是

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

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

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

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

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

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

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

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

WCF技术剖析之十二

数据契约(Data Contract)和数据契约序列化器(DataContractSerializer) 大部分的系统都是以数据为中心的(Data Central),功能的实现表现在对相关数据的正确处理.而数据本身,是有效信息的载体,在不同的环境具有不同的表示.一个分布式的互联系统关注于数据的交换,而数据正常交换的根本前提是参与数据交换的双方对于数据结构的一致性理解.这就为数据的表现提出了要求,为了保证处于不同平台.不同厂商的应用能够正常地进行数据交换,交换的数据必须采用一种大家都能够理解的展现

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

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

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

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

WCF技术剖析之十四:泛型数据契约和集合数据契约(下篇)

在.NET中,所有的集合都实现了IEnumerable接口,比如Array.Hashtable.ArrayList.Stack.Queue等.有的集合要求元素具有相同的类型,这种集合一般通过泛型的方式定义,它们实现另一个接口IEnumerable<T>(IEnumerable<T>本身继承自IEnumerable),这样的集合有List<T>.Dictionary<TKey,TValue>.Stack<T>.Queue<T>等.基于集