知识大全 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
MyCollection : ICollection
MyDictionary : Dictionary
MyCollection : ArrayList…的数据契约名称就是 ArrayOfanyType
MyDictionary : Dictionary
注意 如果是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
具有相同相同键和值类型的所有字典集合也被视为具有相同的数据契约(协定)
接口和实现该接口的具体集合类的数据契约是等价的 例如IList
非泛型集合与Object类型的泛型集合的数据契约等价 例如 List<Object>与ArrayList等价 ArrayList与Object[]也是等价的
这就是为什么上面的示例中 实现IList
[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
所以 针对Customer 的定义 我们可以将实现ICollection
集合与KnowType
集合类型和非集合类型在多态增加KnowType类型方面是不同的 关于非集合方面增加KnowType的详细情况请我以前的文章 WCF Data Contract之KnowType 集合类型在增加KnowType类型遵守以下规则
集合类型是以多态方式来代替其他集合或集合接口的 您不需要将这样的集合类型添加到KnowType类型中 例如上例中Customer 类中的addresses 你可以将List
当您以多态方式使用集合来代替非集合类型时 则需要将它们添加到已知类型 例如 如果您声明一个 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
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
( )如果我们新建的集合类型是实现了集合接口例如IList
( )针对应用CollectionDataContractAttribute属性或者缺省不应用任何属性的集合类型 如果其内部有应用了DataMemberAttribute的属性或字段 在序列化时系统将忽略
WCF中对集合类型的要求限制
不是所有的集合类型都可以在WCF中使用 只有满足以下要求才可以使用
该集合类型有一个缺省的构造函数
该集合类型有一个名为Add的方法
这是因为在反序列化集合类型时 WCF框架首先调用该集合类型的无参数的构造函数 然后通过非静态的Add方法来将循环元素增加到集合中 所以以上限制主要是针对反序列化而设定的
集合中的一些高级规则
WCF框架在序列化时支持集合的集合 也支持数组的数组(交错数组) 但不支持多唯数组
字节数组和 XmlNode 数组是特殊的数组类型 将被视为基元 而不是集合 序列化字节数组会产生单个包含一个 Base 编码数据块的 XML 元素 而不是为每个字节都生成一个单独的元素 (笔者认为这是为了性能的考虑才这么处理的 )
如果集合类型实现了IXMLSerializable接口 假设类型为MyType:IList
在对集合进行序列化时 将调用集合类的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)小编为大家搜集整理
简介WCFDataContract的两个版本 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!中断式改
WCF中的DataContract:DataContract概览 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起
知识大全 讲解Racle缓冲块(Data block)状态类型
讲解Racle缓冲块(Datablock)状态类型 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
按照操作执行所需的资源类型我们可以将操作分为cpu绑定型操作和I/O绑定型操作前者主要是利用cpu进行密集运算后者大部分操作处理时间花在I/O处理上(比如文件系统网络资源)对于I/O绑定型的操作我
Java集合的缺点:类型未知 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 使用Java集合的缺
一起学WCF--wcf初识 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 最近想把有关WCF的内
WCFTips之WCF应用程序的程序集划分 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! WCF
ajax调用WCF服务 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 关于AJAX调用WCF服务
一起学WCF--数据契约 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 这一节我们来了解下WCF