知识大全 WCF Data Contract集合类型

Posted 类型

篇首语:知识的价值不在于占有,而在于使用。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 WCF Data Contract集合类型相关的知识,希望对你有一定的参考价值。

WCF Data Contract集合类型  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  在 Net中将实现了IEnumerable接口的所有类型(包括数组和泛型)都称之为集合类型 把其中实现了IDictionary接口或泛型IDictionary接口的集合类型称为字典集合 剩下的其他集合类型为列表集合

   集合的数据契约(协定)缺省名称      

  缺省情况下 WCF框架对集合类型是内建支持的 也就说你不需要应用任何属性 就可以将集合应用在数据契约(协定)中 但前提是集合中的元素必须是应用了DataContractAttribute属性或者是可序列化的类型 这时 数据契约(协定)名称和命名空间就依赖集合中包含的元素的类型的名称和命名空间了 它们不受集合类型本身的名称和命名空间的影响

  缺省集合类型数据契约(协定)的格式是(不包括 + )

  列表集合 名称 ArrayOf+集合中包含的元素类型循环元素名称 集合中包含的元素类型

  字典集合     名称 ArrayOfKeyValueOf+集合中Key的类型+集合中包含的对象类型循环元素名称 KeyValueOf+集合中Key的类型+集合中包含的对象类型

  例如

  MyCollection : IList …的数据契约名称就是 ArrayOfint

  MyCollection : ICollection …的数据契约名称就是 ArrayOfint

  MyDictionary : Dictionary …的数据契约名称就是 ArrayOfKeyValueOfintint

  MyCollection : ArrayList…的数据契约名称就是 ArrayOfanyType

  MyDictionary : Dictionary …的数据契约名称就是 ArrayOfKeyValueOfintanyType

  注意 如果是object的话 使用的是anyType 因为在Schema中所有类型的基类是anyType

  如果集合是应用于某个数据契约类型中时 那么它的名称将是字段名称 如下面Customer的定义以及序列化后的表示

  

  [DataContract]public class Customer [DataMember]public List<string> addresses = new List<string> Beijing ShangHai ;[DataMember]public Dictionary<int object> telephones = new Dictionary<int object> ;

  <Customer xmlns:i= instance xmlns= ><addresses xmlns:d p = ><d p :string>Beijing</d p :string><d p :string>ShangHai</d p :string></addresses><telephonesxmlns:d p = ><d p :KeyValueOfintanyType><d p :Key> </d p :Key>            

  <d p :Value xmlns:d p =

  i:type= d p :string > </d p :Value>

  </d p :KeyValueOfintanyType><d p :KeyValueOfintanyType><d p :Key> </d p :Key>

  <d p :Value xmlns:d p =

  i:type= d p :string > </d p :Value>

  </d p :KeyValueOfintanyType></telephones></Customer>

   集合的契约等价

  在WCF中应用了CollectionDataContractAttribute属性的集合称之为定制数据契约集合 否则为非定制数据契约集合 不管是非定制数据契约集合还是定制数据契约集合 只要它们的数据契约名称和循环元素的名称都相同(如果是字典集合其Key和Value也要是相同的) 我们就说它们是等价的 由于非定制数据契约集合的数据契约以及循环元素的名称由集合中的类型决定 所以非定制数据契约集合的数据契约等价遵守以下几个规则(关于数据契约等价的其他详细信息请参见我以前的文章 WCF Data Contract之契约等价)

   相同类型的列表集合被认为具有相同的数据契约(协定)例如 List 和int[]是等价的

   具有相同相同键和值类型的所有字典集合也被视为具有相同的数据契约(协定)

   接口和实现该接口的具体集合类的数据契约是等价的 例如IList 和List 等价

   非泛型集合与Object类型的泛型集合的数据契约等价 例如 List<Object>与ArrayList等价 ArrayList与Object[]也是等价的

  这就是为什么上面的示例中 实现IList 和ICollection 的集合类型的数据契约名称都是ArrayOfint的原因 例如下面两个数据契约是等价的

   [DataContract(Name= Customer )] public class Customer [DataMember] public string customerName;[DataMember] public Collection<string> addresses;[DataMember] public string[] telephones;[DataContract(Name= Customer )] public class Customer [DataMember] public string customerName;[DataMember] public ICollection<string> addresses;[DataMember] public List<string> telephones;

  注意 Collection 和ICollection 是等价的 同时string[]和List 也是等价的

  所以 针对Customer 的定义 我们可以将实现ICollection 接口的任何集合类的实例赋给addresses 同样 我们也可以利用在数据契约中定义集合接口的机制来将WCF不支持的集合类型(如 ReadOnlyCollection 具体见本文中WCF中对集合类型的要求限制一节)来应用到我们的WCF应用中 也就是说我们可以将ReadOnlyCollection的实例赋给Customer 的addresses

   集合与KnowType

  集合类型和非集合类型在多态增加KnowType类型方面是不同的 关于非集合方面增加KnowType的详细情况请我以前的文章 WCF Data Contract之KnowType 集合类型在增加KnowType类型遵守以下规则

   集合类型是以多态方式来代替其他集合或集合接口的 您不需要将这样的集合类型添加到KnowType类型中 例如上例中Customer 类中的addresses 你可以将List 的实例赋值给它 而不需要将List 增加到KnowType类型列表中

   当您以多态方式使用集合来代替非集合类型时 则需要将它们添加到已知类型 例如 如果您声明一个 Object 类型的数据成员并将其用于发送 ArrayList 的一个实例 则需要将 ArrayList 添加到已知类型中

   等价的集合只能应用KnowTypeAttribute属性来将其增加到KnowType列表中一次 例如 不能将ArrayList和Object[]都添加到相同类的KnowType列表中

   定制集合的数据契约(协定)      

  我们可以使用CollectionDataContractAttribute的下列属性来指定集合的数据契约的相关名称及命名空间

   Name属性来指定集合数据契约的名称(如果没有使用此属性 将使用集合类型的名称)

   Namespace属性来指定其命名空间

   ItemName 属性来指定循环元素的名称

   针对字典集合还可以用KeyName和ValueName来指定键和值的名称

  例如 我们将第一节的例子更改成如下所示

  

  [CollectionDataContract(Name = telephones ItemName = telephone

  KeyName = Index ValueName = Number )]

  public class MyDictionary : Dictionary

  

  public new Dictionary Enumerator GetEnumerator()

  

  Dictionary innerObject = new Dictionary

  

   ;

  return innerObject GetEnumerator();

  

  

  此类将被序列化成

   >

  

  

  

  

  

  

  

  对于定制数据契约的集合类型来说 前面所述的非定制数据契约的集合等价规则将失效 所以要尽量避免使用CollectionDataContractAttribute

   集合的反序列化

  缺省情况下 使用Svcutil exe生成客户端代理时 列表集合将反序列化成数组 字典集合将反序列化成Dictionary泛型 我们也可以通过/collectionType 命令行开关(简写形式是 /ct)来指定我们希望反序列化的集合类型(请记住 您还必须使用 /reference 开关(简写形式是 /r)指定引用的集合类型的程序集) 如果该类型是泛型 则必须在类型后面跟有反引号和泛型参数的数目 例如前面的例子中的Customer 类可以通过下面的命令在客户端使用List泛型 //localhost: / 

   /r:C:\\WINDOWS\\Microsoft NET\\Framework\\v \\System dll/ct:System Collections Generic List`

   DataContractAttribute和CollectionContractAttribute      

  对于集合而言 WCF框架将隐含地自动的为集合类型应用CollectionDataContractAttribute属性的 这就是为什么你不需要为集合应用任何属性就可以在数据契约中使用的原因 但要注意

  ( )如果我们新建的集合类型是继承已有的集合类型如List 那么我们就不能对新建的集合类型应用DataContractAttribute 否则运行时会抛出InvalidDataContractException 但你可以应用CollectionDataContractAttribute来定制集合类型的数据契约 例如[DataContract]public class MyList:List …的集合定义将抛出异常

  ( )如果我们新建的集合类型是实现了集合接口例如IList IDictionary 的话 我们可以对此类型应用DataContractAttribute属性 这样的话此类型将作为普通的数据契约类型 而不是将其作为集合类型来处理 也就是WCF框架将只序列化其中应用了DataMemberAttribute属性的成员 当然你也可以不应用任何属性来让系统缺省作为集合类型来处理 (你也可以使用CollectionDataContractAttribute来定制数据契约)

  ( )针对应用CollectionDataContractAttribute属性或者缺省不应用任何属性的集合类型 如果其内部有应用了DataMemberAttribute的属性或字段 在序列化时系统将忽略

   WCF中对集合类型的要求限制

  不是所有的集合类型都可以在WCF中使用 只有满足以下要求才可以使用

   该集合类型有一个缺省的构造函数

   该集合类型有一个名为Add的方法

  这是因为在反序列化集合类型时 WCF框架首先调用该集合类型的无参数的构造函数 然后通过非静态的Add方法来将循环元素增加到集合中 所以以上限制主要是针对反序列化而设定的

   集合中的一些高级规则

   WCF框架在序列化时支持集合的集合 也支持数组的数组(交错数组) 但不支持多唯数组

   字节数组和 XmlNode 数组是特殊的数组类型 将被视为基元 而不是集合 序列化字节数组会产生单个包含一个 Base 编码数据块的 XML 元素 而不是为每个字节都生成一个单独的元素 (笔者认为这是为了性能的考虑才这么处理的 )

   如果集合类型实现了IXMLSerializable接口 假设类型为MyType:IList IXMLSerializable… WCF框架将根据在数据契约中声明的类型来进行序列化 如果声明的是集(接口)如IList 那么该类型将被认为是列表集合来序列化 如果声明的是IXMLSerializable 那么将按照IXMLSerializable来进行序列化 当然需要将该类型加到KnowType类型列表中 如果声明的是该类型本身(如MyType) 那么将按照IXMLSerializable的规则来进行序列化

   在对集合进行序列化时 将调用集合类的GetEnumerator 方法来得到集合的内容 在反序列化时将首先调用该集合类型的无参数的构造函数 然后通过非静态的Add方法来将循环元素增加到集合中 (注 虽然这与大家在MSDN的帮助文档中看到的不同 认为字典集合将调用get_Keys和get_Values 以及IList将调用索引器 但笔者使用VS 验证时没有得到以上方法被调用的结论 所以笔者认为是MSDN文档滞后或有误 如果各位看官能得到和MSDN吻合的结论麻烦告诉一声 )

   如果集合类型同时应用了Serialized属性或实现了ISerializable接口 WCF框架将忽略它们 但是如果集合类型不满足集合类型要求(例如缺少Add)方法 那么将按照Serialized或ISerializable来处理 但如果你对该集合同时应用了CollectionDataContract属性而且又不满足集合要求 那么将抛出InvalidDataContractException 而不是按照Serialized或ISerializable来处理

   不能向实现了IXmlSerializable接口的类型使用CollectionDataContractAttribute属性 否则会抛出InvalidDataContractException 向非集合应用CollectionDataContractAttribute属性以及非字典集合指定KeyName或者ValueName属性也都将抛出此异常

cha138/Article/program/net/201311/12431

相关参考

知识大全 WCF Data Contract对Collection和D

WCF中的DataContract:WCFDataContract对Collection和D  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理

知识大全 简介WCF Data Contract的两个版本

简介WCFDataContract的两个版本  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!中断式改

知识大全 Data Contract概览

WCF中的DataContract:DataContract概览  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起

知识大全 讲解Racle缓冲块(Data block)状态类型

讲解Racle缓冲块(Datablock)状态类型  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 

知识大全 wcf多线程和异步操作

  按照操作执行所需的资源类型我们可以将操作分为cpu绑定型操作和I/O绑定型操作前者主要是利用cpu进行密集运算后者大部分操作处理时间花在I/O处理上(比如文件系统网络资源)对于I/O绑定型的操作我

知识大全 类型未知

Java集合的缺点:类型未知  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  使用Java集合的缺

知识大全 一起学WCF--wcf初识

一起学WCF--wcf初识  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  最近想把有关WCF的内

知识大全 WCF Tips之WCF应用程序的程序集划分

WCFTips之WCF应用程序的程序集划分  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  WCF

知识大全 ajax调用WCF服务

ajax调用WCF服务  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  关于AJAX调用WCF服务

知识大全 一起学WCF--数据契约

一起学WCF--数据契约  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  这一节我们来了解下WCF