好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

WCF中的集合类型

WCF中的集合类型

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特性

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

它要求集合必须可序列化,而不是使用DataContract特性。 当服务的一方处理集合类型时,服务的另外一方若处理数组类型,就会导致双方语义不对称,集合拥有数组不具备的优势。 对于集合是否包含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应用到集合类型上,在装载服务的时候同样会检查这一点。

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于WCF中的集合类型的详细内容...

  阅读:43次