zoukankan      html  css  js  c++  java
  • 艾伟:[原创]谈谈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

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

     

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

            [DataMember]
            
    public DateTime OrderDate
            
    getset; }
        }


        
    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一项我们有若干选项,我们可以选择我们希望生成的数据类型:ArrayArrayListLinkedListGeneric ListCollectionBindingList 

    Data Contract for Dictionary

    前面的内容,我们分别讨论了基于GenericCollectionData Contract,接下来,我们来讨论最后一个特殊的数据类型的Data ContractDictionary

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

    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
            
    getset; }

            [DataMember]
            
    public DateTime OrderDate
            
    getset; }
        }

    闲话少说,我们来看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+guidKey的类型)+OrderValue+_SkVQi6O3Hash Value)。从该XSD的结构我们不难看出,只是一个数组,每个元素为Key-Value pair

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

        [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一样,也依然可以有多种选择:

  • 相关阅读:
    JZOJ 3034. 【NOIP2012模拟10.17】独立集
    JZOJ 3035. 【NOIP2012模拟10.17】铁轨
    JZOJ 1259. 牛棚安排
    数位DP JZOJ 3316. 非回文数字
    JZOJ 3046. 游戏
    JZOJ 3013. 填充棋盘
    debian 安装oracle提供的java8
    java 汉字转拼音 PinYin4j
    debian ssh设置root权限登陆 Permission denied, please try again
    java并发下订单生成策略
  • 原文地址:https://www.cnblogs.com/waw/p/2156969.html
Copyright © 2011-2022 走看看