WCF中的集合类型

在.net中,各种类型的集合均实现了IEnumerable或者IEnumerable<T>接口,一个数据契约的数据成员可以是一个集合类型,服务契约也可以定义直接与集合交互的操作,但是这都是.net所特有的,WCf不能在元数据中公开它们,然后WCF专门为集合提供了编组原则。

     在定义服务时候,无论使用的是IEnumerable<T>、IList<T>和ICollection<T>,他们的传输形式都使用了数组,如

namespace ContractInterface

{

    [ServiceContract]

public interface IContractManager

    {

        [ OperationContract]

IEnumerable<Contract> GetContracts();

    }

}

导出的结果为

public interface IContractManager

{

Contract[] GetContracts();

    }

如果契约中的集合为具体集合类型而非接口,而且属于可序列化集合,那么只要提供的集合包含了Add方法,并且符合以下签名中的一种,WCF就能够自动地将集合规范为数组类型。

     并非只有内建的集合类型才具有自动编组为数组的能力,任何自定义的集合只要符合相同的先决条件,都可以被编组为数组。

CollectionDataContract特性

前面所示的编组为具体类型的机制并不理想,原有有三

  1. 它要求集合必须可序列化,而不是使用DataContract特性。
  2. 当服务的一方处理集合类型时,服务的另外一方若处理数组类型,就会导致双方语义不对称,集合拥有数组不具备的优势。
  3. 对于集合是否包含Add方法,或者集合是否支持IEnumerable和IEnumerable<T>接口,并没有编译时或者运行时的有效验证。如果不符合条件,就会导致数据契约不可工作。

基于以上几点,WCF提供了另外一种有效的解决方案,一种专用的特性:CollectionDataContractAttribute,定义为:

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false , AllowMultiple = false)]

public sealed class CollectionDataContractAttribute : Attribute

    {

public CollectionDataContractAttribute();

public bool IsReference { get; set; }

public string ItemName { get; set; }

public string KeyName { get; set; }

public string Name { get; set; }

public string Namespace { get; set; }

public string ValueName { get; set; }

    }

CollectionDataContract和DataContract相似,它不能序列化集合,将它应用到一个集合上时,会将集合当作一个泛型的链表类型公开给客户端链表可能不会对原来的集合执行任何操作,但它会提供一个类似接口的集合类型,而不是数组。例如,定义如下类型:

namespace ContractInterface

{

    [CollectionDataContract(Name= "MyCollectionOf{0}")]

public class MyCollection<T>: IEnumerable<T>

    {

public void Add(T item)

        { }

public IEnumerator<T> GetEnumerator()

        {

throw new NotImplementedException();

        }

    }

}

服务契约修改为:

namespace ContractInterface

{

    [ServiceContract]

public interface IContractManager

    {

        [ OperationContract]

List<Contract> GetContracts();

[OperationContract ]

MyCollection<Contract> GetContract();

    }

}

则,导出的客户端定义为:

MyCollectionOfContract GetContract();

集合类重新编组为

public class MyCollectionOfContract : System.Collections.Generic.List<Contract > {

    }

     在装载服务时,特性会检查Add方法和IEnumerable或者IEnumerable<T>是否存在,如果不存在而引发InvalidDataContractException异常。

     注意,不能同时将DataContract和CollecctionDataContract应用到集合类型上,在装载服务的时候同样会检查这一点。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏JackieZheng

并发和多线程-八面玲珑的synchronized

上篇《并发和多线程-说说面试常考平时少用的volatile》主要介绍的是volatile的可见性、原子性等特性,同时也通过一些实例简单与synchronized...

1003
来自专栏10km的专栏

thrift/swift:ThriftMethodProcessor代码分析

thrift是一种跨语言的RPC框架,为了保证在各种语言下都能正确表述,IDL语言在设计的时候就只能选取各种语言的共性。 比如对于null,虽然在java中...

1768
来自专栏Java面试笔试题

Java中如何实现序列化,有什么意义?

序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决对象...

1294
来自专栏WindCoder

JSON中关于对双向关联的支持

本文原文:Bidirectional Relationship Support in JSON

1122
来自专栏向治洪

Swift 4.0 新特性

WWDC 2017 带来了很多惊喜,在这次大会上,Swift 4 也伴随着 Xcode 9 测试版来到了我们的面前,虽然正式版要8月底9月初才会公布,但很多强大...

2099
来自专栏跟着阿笨一起玩NET

C# TextBox 扩展方法数据验证

      查看公司项目代码时,存在这样一个问题:winform界面上有很多信息填写,提交后台服务器更新,但数据的合法验证及值的转换却不太敢恭维,一堆的if判断...

371
来自专栏博岩Java大讲堂

关于Java泛型"擦除"的一点思考

2665
来自专栏Linyb极客之路

java代码优化的若干细节

代码优化,一个很重要的课题。可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼...

1104
来自专栏章鱼的慢慢技术路

牛客网_Go语言相关练习_判断&选择题(4)

错误指的是可能出现问题的地方出现了问题,比如打开一个文件时失败,这种情况在人们的意料之中;而异常指的是不应该出现问题的地方出现了问题,比如引用了空指针,这种情况...

892
来自专栏Python中文社区

Python源码剖析之整数对象

專 欄 ❈ 松直,Python中文社区专栏作者 专栏地址: http://www.zhihu.com/people/songzhili?utm_source...

2108

扫码关注云+社区