`
varsoft
  • 浏览: 2439128 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

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

阅读更多

[爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道《天天山海经》为此录制的节目视频(苏州话)]]如果一个类型,不一定是数据契约,和给定的数据契约具有很大的差异,而我们要将该类型的对象序列化成基于数据契约对应的XML。反之,对于一段给定的基于数据契约的XML,要通过反序列化生成该类型的对象,我们该如何实现这样的场景?

比如下面定义了两个类型Contact和Customer,其中Customer是数据契约,Contact的Sex属性相当于Customer的Gender属性,而Contact的FullName可以看成是Customer的FirstName和LastName的组合。现在我们要做的是将一个Contact对象序列化成基于Customer数据契约对应的结构的XML,或者对于一段基于Customer数据契约对应结构的XML,将其反序列化生成Contact对象。

   1: public class Contact
<!--CRLF-->
   2: {
<!--CRLF-->
   3:     public string FullName
<!--CRLF-->
   4:     { get; set; }
<!--CRLF-->
   5: 
<!--CRLF-->
   6:     public string Sex
<!--CRLF-->
   7:     { get; set; }
<!--CRLF-->
   8: 
<!--CRLF-->
   9:     public override bool Equals(object obj)
<!--CRLF-->
  10:     {
<!--CRLF-->
  11:         Contact contact = obj as Contact;
<!--CRLF-->
  12:         if (contact == null)
<!--CRLF-->
  13:         {
<!--CRLF-->
  14:             return false;
<!--CRLF-->
  15:         }
<!--CRLF-->
  16: 
<!--CRLF-->
  17:         return this.FullName == contact.FullName && this.Sex == contact.Sex;
<!--CRLF-->
  18:     }
<!--CRLF-->
  19: 
<!--CRLF-->
  20:     public override int GetHashCode()
<!--CRLF-->
  21:     {
<!--CRLF-->
  22:         return this.FullName.GetHashCode() ^ this.Sex.GetHashCode();
<!--CRLF-->
  23:     }
<!--CRLF-->
  24: }
<!--CRLF-->
   1: [DataContract(Namespace = "http://www.artech.com")]
<!--CRLF-->
   2: public class Customer
<!--CRLF-->
   3: {
<!--CRLF-->
   4:     [DataMember(Order = 1)]
<!--CRLF-->
   5:     public string FirstName
<!--CRLF-->
   6:     { get; set; }
<!--CRLF-->
   7: 
<!--CRLF-->
   8:     [DataMember(Order = 2)]
<!--CRLF-->
   9:     public string LastName
<!--CRLF-->
  10:     { get; set; }
<!--CRLF-->
  11: 
<!--CRLF-->
  12:     [DataMember(Order = 3)]
<!--CRLF-->
  13:     public string Gender
<!--CRLF-->
  14:     { get; set; }
<!--CRLF-->
  15: }
<!--CRLF-->

为实现上面的要求,要涉及WCF中一个特殊的概念:数据契约代理(DataContract Surrogate)。WCF通过一个接口System.Runtime.Serialization.IDataContractSurrogate来表示数据契约代理。IDataContractSurrogate用于实现在序列化、反序列化、数据契约的导入和导出过程中对对象或者类型的替换。以上面Contact和Customer为例,在正常的情况下,DataContractSerializer针对类型Customer对一个真正的Customer对象进行序列化,现在要求的是通过DataContractSerializer序列化一个Contact对象,并且要生成与Customer等效的XML,就要在序列化的过程中实现类型的替换(由Contact类型替换成Customer类型)和对象的替换(由Contact对象替换成Customer对象)。

我们先来看看IDataContractSurrogate的定义,序列化相关的方法有以下3个,如果想具体了解IDataContractSurrogate在数据契约导入、导出,以及代码生成方面的应用可以参考MSDN相关文档,在这里就不多作介绍了。

  • GetDataContractType:获取进行序列化、反序列化或者数据契约导入导出基于的数据契约的类型,实现此方法相当于实现了类型的替换;
  • GetObjectToSerialize:在序列化之前获取序列化的对象,实现了此方法相当于为序列化实现了对象替换;
  • GetDeserializedObject:当完成反序列化工作后,通过方法获得被反序列化生成的对象,通过此方法可以用新的对象替换掉真正被反序列化生成的原对象。
   1: public interface IDataContractSurrogate
<!--CRLF-->
   2: {
<!--CRLF-->
   3:     Type GetDataContractType(Type type);
<!--CRLF-->
   4:     object GetObjectToSerialize(object obj, Type targetType);
<!--CRLF-->
   5:     object GetDeserializedObject(object obj, Type targetType);
<!--CRLF-->
   6: 
<!--CRLF-->
   7:     object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType);
<!--CRLF-->
   8:     object GetCustomDataToExport(Type clrType, Type dataContractType);    
<!--CRLF-->
   9:     void GetKnownCustomDataTypes(Collection<Type> customDataTypes);    
<!--CRLF-->
  10:     Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData);
<!--CRLF-->
  11:     CodeTypeDeclaration ProcessImportedType(CodeTypeDeclaration typeDeclaration, CodeCompileUnit compileUnit);
<!--CRLF-->
  12: }
<!--CRLF-->

现在我专门为Contact和Customer之间的转换创建了一个自定义的DataContractSurrogate:ContractSurrogate。在GetDataContractType中,如果发现类型是Contact,则替换成Customer。在GetObjectToSerialize方法中,将用于序列化的Contact对象用Customer对象替换,而在GetDeserializedObject中则用Contact对象替换反序列化生成的Customer对象。

   1: public class ContractSurrogate : IDataContractSurrogate
<!--CRLF-->
   2: {
<!--CRLF-->
   3: 
<!--CRLF-->
   4:     public object GetCustomDataToExport(Type clrType, Type dataContractType)
<!--CRLF-->
   5:     {
<!--CRLF-->
   6:         return null;
<!--CRLF-->
   7:     }
<!--CRLF-->
   8: 
<!--CRLF-->
   9:     public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType)
<!--CRLF-->
  10:     {
<!--CRLF-->
  11:         return null;
<!--CRLF-->
  12:     }
<!--CRLF-->
  13: 
<!--CRLF-->
  14:     public Type GetDataContractType(Type type)
<!--CRLF-->
  15:     {
<!--CRLF-->
  16:         if (type == typeof(Contact))
<!--CRLF-->
  17:         {
<!--CRLF-->
  18:             return typeof(Customer);
<!--CRLF-->
  19:         }
<!--CRLF-->
  20: 
<!--CRLF-->
  21:         return type;
<!--CRLF-->
  22:     }
<!--CRLF-->
  23: 
<!--CRLF-->
  24:     public object GetDeserializedObject(object obj, Type targetType)
<!--CRLF-->
  25:     {
<!--CRLF-->
  26:         Customer customer = obj as Customer;
<!--CRLF-->
  27:         if (customer == null)
<!--CRLF-->
  28:         {
<!--CRLF-->
  29:             return obj;
<!--CRLF-->
  30:         }
<!--CRLF-->
  31: 
<!--CRLF-->
  32:         return new Contact
<!--CRLF-->
  33:         {
<!--CRLF-->
  34:             FullName = string.Format("{0} {1}", customer.FirstName, customer.LastName),
<!--CRLF-->
  35:             Sex = customer.Gender
<!--CRLF-->
  36:         };
<!--CRLF-->
  37:     }
<!--CRLF-->
  38: 
<!--CRLF-->
  39:     public void GetKnownCustomDataTypes(Collection<Type> customDataTypes)
<!--CRLF-->
  40:     {
<!--CRLF-->
  41: 
<!--CRLF-->
  42:     }
<!--CRLF-->
  43: 
<!--CRLF-->
  44:     public object GetObjectToSerialize(object obj, Type targetType)
<!--CRLF-->
  45:     {
<!--CRLF-->
  46:         Contact contact = obj as Contact;
<!--CRLF-->
  47:         if (contact == null)
<!--CRLF-->
  48:         {
<!--CRLF-->
  49:             return obj;
<!--CRLF-->
  50:         }
<!--CRLF-->
  51: 
<!--CRLF-->
  52: 
<!--CRLF-->
  53:         return new Customer
<!--CRLF-->
  54:         {
<!--CRLF-->
  55:             FirstName = contact.FullName.Split(" ".ToCharArray())[0],
<!--CRLF-->
  56:             LastName = contact.FullName.Split(" ".ToCharArray())[1],
<!--CRLF-->
  57:             Gender = contact.Sex
<!--CRLF-->
  58:         };
<!--CRLF-->
  59:     }
<!--CRLF-->
  60: 
<!--CRLF-->
  61:     public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
<!--CRLF-->
border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style

  


  
分享到:
评论

相关推荐

    WCF技术剖析.pdf

    《WCF技术剖析》从WCF的终结点谈起,对终结点的三要素进行了全面而深入的介绍,帮助读者了解地址、绑定和契约的本质。 通过本书对序列化的深入讲解,读者可了解WCF进行操作方法调用与消息之间转化的本质;深入剖析...

    WCF全面解析(套装上下册) 高清pdf 带书签 part2(共4)

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章...

    WCF全面解析(下册)

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章...

    WCF全面解析01

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章...

    WCF全面解析 下册

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章...

    WCF全面解析07

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章...

    第一卷wcf技术剖析

    从WCF的终结点谈起,对终结点...通过本书对序列化的深入讲解,读者可了解WCF进行操作方法调用与消息之间转化的本质. 另外,本书提供了一个完整的案例帮助读者掌握如何利用本书涉及的内容搭建一个基本的WCF分布式应用。.

    WCF全面解析(套装上下册) 高清pdf 带书签part1(共4)

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章...

    WCF全面解析

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章...

    WCF全面解析(源码)

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章...

    WCF全面解析(上册)

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章...

    WCF全面解析(套装上下册) 高清pdf 带书签 part3(共4)

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章...

    WCF 全面解析第三节pdf

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章...

    wcf 全面解析(上)

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和rest服务上面;在最后一章...

    WCF全面解析05

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章...

    WCF全面解析04

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章...

    WCF全面解析03

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章...

    WCF全面解析06

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章...

    WCF全面解析 下册.part2

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章...

    WCF全面解析 上册

    随后的两章则着重剖析序列化和消息编码在WCF中的实现;第7、8章讲述了在服务寄宿和操作调用过程中,WCF的服务端和客户端框架分别为我们做了什么;第9、10章将介绍的重点落在实例化、会话和REST服务上面;在最后一章...

Global site tag (gtag.js) - Google Analytics