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

时间:2021-02-08 14:54:09

谈谈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:

谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持namespace Artech.SpecialDataContract.Contract
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持{
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    [DataContract]
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    public class Order
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    {
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        [DataMember]
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        public Guid OrderID
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        { get; set; }
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        [DataMember]
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        public DateTime OrderDate
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        { get; set; }
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    }
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    public class OrderCollection : List<Order>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    {
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    }
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持}
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持

下面是Service Contract的定义:

谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持namespace Artech.SpecialDataContract.Contract
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持{
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    [ServiceContract]
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    public interface IOrderManager
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    {
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        [OperationContract(Name = "ProcessWithCollection")]
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        void Process(OrderCollection orders);
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持}
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持

面是OrderCollection 在XSD中的呈现:

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

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

谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    [System.ServiceModel.ServiceContractAttribute(ConfigurationName="OrderManagerService.IOrderManager")]
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    public interface IOrderManager { 
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IOrderManager/ProcessWithCollection", ReplyAction="http://tempuri.org/IOrderManager/ProcessWithCollectionResponse")]
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        void ProcessWithCollection(Artech.SpecialDataContract.Client.OrderManagerService.Order[] orders);
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持}
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持

因为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的定义:

谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持namespace Artech.SpecialDataContract.Contract
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持{
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    [ServiceContract]
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    public interface IOrderManager
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    {
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        [OperationContract(Name = "ProcessWithCollection")]
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        void Process(OrderCollection orders);
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        [OperationContract(Name = "ProcessWithDictionary")]
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        void Process(IDictionary<Guid, Order> orders);
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    }
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持}
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    [DataContract]
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    public class Order
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    {
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        [DataMember]
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        public Guid OrderID
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        { get; set; }
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        [DataMember]
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        public DateTime OrderDate
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        { get; set; }
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    }
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持

闲话少说,我们来看XSD:

谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持<?xml version="1.0" encoding="utf-8"?>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持<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/">
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持  <xs:import schemaLocation="http://artech/Artech.SpecialDataContract/OrderManagerService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持  <xs:import schemaLocation="http://artech/Artech.SpecialDataContract/OrderManagerService.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/Artech.SpecialDataContract.Contract"/>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持  <xs:complexType name="ArrayOfKeyValueOfguidOrder_SkVQi6O3">
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    <xs:annotation>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持      <xs:appinfo>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        <IsDictionary xmlns="http://schemas.microsoft.com/2003/10/Serialization/">true</IsDictionary>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持      </xs:appinfo>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    </xs:annotation>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    <xs:sequence>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持      <xs:element minOccurs="0" maxOccurs="unbounded" name="KeyValueOfguidOrder_SkVQi6O3">
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        <xs:complexType>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持          <xs:sequence>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持            <xs:element name="Key" type="ser:guid"/>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持            <xs:element name="Value" nillable="true" type="q1:Order" xmlns:q1="http://schemas.datacontract.org/2004/07/Artech.SpecialDataContract.Contract"/>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持          </xs:sequence>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        </xs:complexType>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持      </xs:element>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    </xs:sequence>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持  </xs:complexType>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持  <xs:element name="ArrayOfKeyValueOfguidOrder_SkVQi6O3" nillable="true" type="tns:ArrayOfKeyValueOfguidOrder_SkVQi6O3"/>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持</xs:schema>
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持

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

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

谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    [System.ServiceModel.ServiceContractAttribute(ConfigurationName="OrderManagerService.IOrderManager")]
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    public interface IOrderManager {               
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IOrderManager/ProcessWithDictionary", ReplyAction="http://tempuri.org/IOrderManager/ProcessWithDictionaryResponse")]
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持        void ProcessWithDictionary(System.Collections.Generic.Dictionary<System.Guid, Artech.SpecialDataContract.Client.OrderManagerService.Order> orders);
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持    }
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持

生成的是一个System.Collections.Generic.Dictionary类型。同Collection一样,也依然可以有多种选择:
谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持