程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 談談WCF中的Data Contract(3)

談談WCF中的Data Contract(3)

編輯:關於.NET

談談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一樣,也依然可以有多種選擇:

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved