谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持

在本篇文章上一部分Order Processing的例子中,我们看到原本已Collection形式定义的DetailList属性(public IList<TDetail> DetailList),在Data Contract中却以Array的方式体现(public OrderDetail[] DetailList)。我们现在就来详细地讨论一下基于Collection & Dictionary 的Data Contract。

Data Contract for Collection

我们照例用例子来说明问题,在这里我们创建一个批量处理Order的Service,于是我们创建了一个OrderCollection Type:

namespace Artech.SpecialDataContract.Contract
{
    [DataContract]
    public class Order
    {
        [DataMember]
        public Guid OrderID
        { get; set; }

        [DataMember]
        public DateTime OrderDate
        { get; set; }
    }

    public class OrderCollection : List<Order>
    {

    }
}

下面是Service Contract的定义:

namespace Artech.SpecialDataContract.Contract
{
    [ServiceContract]
    public interface IOrderManager
    {
        [OperationContract(Name = "ProcessWithCollection")]
        void Process(OrderCollection orders);
}

面是OrderCollection 在XSD中的呈现:

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/Artech.SpecialDataContract.Contract"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.datacontract.org/2004/07/Artech.SpecialDataContract.Contract"
    xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/">
  <xs:import schemaLocation="http://artech/Artech.SpecialDataContract/OrderManagerService.svc?xsd=xsd1"
          namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
  <xs:complexType name="ArrayOfOrder">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="Order" nillable="true" type="tns:Order" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="ArrayOfOrder" nillable="true" type="tns:ArrayOfOrder"/>
  <xs:complexType
name="Order">
    <xs:sequence>
      <xs:element minOccurs="0" name="OrderDate" type="xs:dateTime"/>
      <xs:element
minOccurs="0" name="OrderID" type="ser:guid"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element
name="Order" nillable="true" type="tns:Order"/>
</xs:schema>

加上通过Add Service Reference默认生成的Class,我们可以很清楚地看出Collection是以Array的形式呈现的(Artech.SpecialDataContract.Client.OrderManagerService.Order[] orders):

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(ConfigurationName="OrderManagerService.IOrderManager")]
    public interface IOrderManager { 
        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IOrderManager/ProcessWithCollection", ReplyAction="http://tempuri.org/IOrderManager/ProcessWithCollectionResponse")]
        void ProcessWithCollection(Artech.SpecialDataContract.Client.OrderManagerService.Order[] orders);
}

因为Array相对很Common的数据类型,基本上所有的厂商均提供了对Array的支持,这也是WCF在通过Add Service Reference生成Client端代码的时候,会生成Array的原因。不过并不是我们只有唯一的选择,事实上VS为此提供了扩展,允许我们对于基于Collection 的Data Contract生成我们需要的各种类型,我们只需要在Add Service Reference的时候选择“Configure Service Reference”进行相应的配置:

通过上面的截图,我们发现在Collection Type一项我们有若干选项,我们可以选择我们希望生成的数据类型:Array,ArrayList,LinkedList,Generic List,Collection和BindingList。 

Data Contract for Dictionary

前面的内容,我们分别讨论了基于Generic和Collection的Data Contract,接下来,我们来讨论最后一个特殊的数据类型的Data Contract:Dictionary。

延续上面的Order Batch Processing的例子,不过我们现在处理的不是一个OrderCollection对象,而是一个Dictionary对象,线面是Service Contract和Order的定义:

namespace Artech.SpecialDataContract.Contract
{
    [ServiceContract]
    public interface IOrderManager
    {
        [OperationContract(Name = "ProcessWithCollection")]
        void Process(OrderCollection orders);

        [OperationContract(Name = "ProcessWithDictionary")]
        void Process(IDictionary<Guid, Order> orders);
    }
}
    [DataContract]
    public class Order
    {
        [DataMember]
        public Guid OrderID
        { get; set; }

        [DataMember]
        public DateTime OrderDate
        { get; set; }
    }

闲话少说,我们来看XSD:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/">
  <xs:import schemaLocation="http://artech/Artech.SpecialDataContract/OrderManagerService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
  <xs:import schemaLocation="http://artech/Artech.SpecialDataContract/OrderManagerService.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/Artech.SpecialDataContract.Contract"/>
  <xs:complexType name="ArrayOfKeyValueOfguidOrder_SkVQi6O3">
    <xs:annotation>
      <xs:appinfo>
        <IsDictionary xmlns="http://schemas.microsoft.com/2003/10/Serialization/">true</IsDictionary>
      </xs:appinfo>
    </xs:annotation>
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="KeyValueOfguidOrder_SkVQi6O3">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="Key" type="ser:guid"/>
            <xs:element name="Value" nillable="true" type="q1:Order" xmlns:q1="http://schemas.datacontract.org/2004/07/Artech.SpecialDataContract.Contract"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
  <xs:element name="ArrayOfKeyValueOfguidOrder_SkVQi6O3" nillable="true" type="tns:ArrayOfKeyValueOfguidOrder_SkVQi6O3"/>
</xs:schema>

Data Contract的名称为ArrayOfKeyValueOfguidOrder_SkVQi6O3=ArrayOfKeyValueOf+guid(Key的类型)+Order(Value)+_SkVQi6O3(Hash Value)。从该XSD的结构我们不难看出,只是一个数组,每个元素为Key-Value pair。

我们照例看看通过Add Service Reference方式生成的Client端code中的对应的定义:

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(ConfigurationName="OrderManagerService.IOrderManager")]
    public interface IOrderManager {               
        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IOrderManager/ProcessWithDictionary", ReplyAction="http://tempuri.org/IOrderManager/ProcessWithDictionaryResponse")]
        void ProcessWithDictionary(System.Collections.Generic.Dictionary<System.Guid, Artech.SpecialDataContract.Client.OrderManagerService.Order> orders);
    }

生成的是一个System.Collections.Generic.Dictionary类型。同Collection一样,也依然可以有多种选择:

谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持的更多相关文章

  1. WCF初探-26:WCF中的会话

    理解WCF中的会话机制 在WCF应用程序中,会话将一组消息相互关联,从而形成对话.会话”是在两个终结点之间发送的所有消息的一种相互关系.当某个服务协定指定它需要会话时,该协定会指定所有调用(即,支持调 ...

  2. WCF中配置文件解析

    WCF中配置文件解析[1] 2014-06-14 WCF中配置文件解析 参考 WCF中配置文件解析 返回 在WCF Service Configuration Editor的使用中,我们通过配置工具自 ...

  3. wcf中的使用全双工通信(转)

    wcf中的使用全双工通信   wcf中的契约通信默认是请求恢复的方式,当客户端发出请求后,一直到服务端回复时,才可以继续执行下面的代码. 除了使用请求应答方式的通信外,还可以使用全双工.下面给出例子: ...

  4. WCF学习之旅—WCF中传统的异常处理(十六)

    WCF中的异常处理 在软件开发过程中,不可能没有异常的出现,所以在开发过程中,对不可预知的异常进行解决时,异常处理显得尤为重要.对于一般的.NET系统来说,我们简单地借助try/catch可以很容易地 ...

  5. wcf中的使用全双工通信

    wcf中的契约通信默认是请求恢复的方式,当客户端发出请求后,一直到服务端回复时,才可以继续执行下面的代码. 除了使用请求应答方式的通信外,还可以使用全双工.下面给出例子: 1.添加一个wcf类库 2. ...

  6. [No0000126]SSL/TLS原理详解与WCF中的WS-Security

    SSL/TLS作为一种互联网安全加密技术 1. SSL/TLS概览 1.1 整体结构 SSL是一个介于HTTP协议与TCP之间的一个可选层,其位置大致如下: SSL:(Secure Socket La ...

  7. 理解WCF中的Contracts

    WCF中的Contracts WCF通过Contract来说明服务和操作,一般包含五种类型的Contract:ServiceContract,OperationContract,FaultContra ...

  8. 浅议Grpc传输机制和WCF中的回调机制的代码迁移

    浅议Grpc传输机制和WCF中的回调机制的代码迁移 一.引子 如您所知,gRPC是目前比较常见的rpc框架,可以方便的作为服务与服务之间的通信基础设施,为构建微服务体系提供非常强有力的支持. 而基于. ...

  9. WCF中,通过C#代码或App.config配置文件创建ServiceHost类

    C# static void Main(string[] args) { //创建宿主的基地址 Uri baseAddress = new Uri("http://localhost:808 ...

随机推荐

  1. 一步一步学习C++

    根据<C++ primer>第五版 总结学习心得. 在实践中,不必全面地使用C++语言的各种特性,而应根据工程的实际情况,适当取舍(譬如动态类型信息,虚拟继承.异常等特性的使用,很值得商榷 ...

  2. search help 概述

    所谓search help 就是在前台调出一个query 得到一个value list 让用户选择需要的值 我们要做的就是给某些表/视图 设计一个可供查询的query 然后把这个query绑定到需要的 ...

  3. OOA、OOD、OOP

      复习 OOA.OOD.OOP OOA Object-Oriented Analysis:面向对象分析方法 是在一个系统的开发过程中进行了系统业务调查以后,按照面向对象的思想来分析问题.OOA与结构 ...

  4. python自定义日志函数测试

    #!/user/bin/python # -*- encoding: UTF-8 -*- import sys def logs(): print sys._getframe().f_code.co_ ...

  5. ubuntu 14.04 下FTP服务器的搭建--锁定用户目录,解决vsftpd: refusing to run with writable root inside chroot()

    FTP服务器的搭建,我要实现的需求是: 不允许匿名访问,因为我的机器不想让谁都能登录上来,随便获取文件, 需要锁定一个目录,因为在家里,我需要给媳妇下载一些电影 韩剧之类的东西,媳妇会来我机器下载,但 ...

  6. HTML5 Shiv – 让该死的IE系列支持HTML5吧

    HTML5能为我们做的事儿很多,最为可口的就是语义化标签的应用,如果你已经在Chrome或者其他支持HTML5的浏览器上用过它的牛x,那这篇文章对你一定有用,因为现在你也可以在IE上用到HTML5. ...

  7. Zendframework 模块加载事件触发顺序。

    模块加载时事件触发的时间顺序: 0.loadModules(ModuleEvent::EVENT_LOAD_MODULES) 1.  loadModule.resolve(ModuleEvent::E ...

  8. c++各种数据类型表示范围

    符号属性     长度属性     基本型     所占位数     取值范围       输入符举例      输出符举例 --            --          char        ...

  9. Input event驱动

    Input event驱动 Linux 专门对输入设备. 键盘,鼠标,手柄,触摸屏.按键.封装一个类驱动. 主要统一与应用程序接口.这一类的设备结点都是在/dev/input/eventn( 0< ...

  10. 从零开始学ios开发(十):Multiview Applications(多个xib之前的切换)

    这篇学习的主要内容是Multiview,在我们学习iphone旋转的时候,介绍过多个view的使用方法,不过这里的view和旋转屏幕中所指的多个view是不同的,旋转屏幕中涉及到的多个view是在一个 ...