[原创]谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持...

本文深入探讨了WCF中基于Collection和Dictionary的DataContract定义及其实现方式,包括不同类型的Collection如何映射到XSD和客户端代码,以及如何通过配置选择不同的集合类型。
在本篇文章上一部分 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]
publicclassOrder
{
[DataMember]
publicGuidOrderID
{get;set;}

[DataMember]
publicDateTimeOrderDate
{get;set;}
}


publicclassOrderCollection:List<Order>
{

}

}

下面是Service Contract的定义:

namespace Artech.SpecialDataContract.Contract
{
[ServiceContract]
publicinterfaceIOrderManager
{
[OperationContract(Name
="ProcessWithCollection")]
voidProcess(OrderCollectionorders);
}

面是OrderCollection 在XSD中的呈现:

<? xmlversion="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")]
voidProcessWithCollection(Artech.SpecialDataContract.Client.OrderManagerService.Order[]orders);
}

因为Array相对很Common的数据类型,基本上所有的厂商均提供了对Array的支持,这也是WCF在通过AddService 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]
publicinterfaceIOrderManager
{
[OperationContract(Name
="ProcessWithCollection")]
voidProcess(OrderCollectionorders);

[OperationContract(Name
="ProcessWithDictionary")]
voidProcess(IDictionary<Guid,Order>orders);
}

}

[DataContract]
public class Order
{
[DataMember]
publicGuidOrderID
{get;set;}

[DataMember]
publicDateTimeOrderDate
{get;set;}
}

闲话少说,我们来看XSD:

<? xmlversion="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")]
voidProcessWithDictionary(System.Collections.Generic.Dictionary<System.Guid,Artech.SpecialDataContract.Client.OrderManagerService.Order>orders);
}

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


[原创]谈谈WCF中的Data Contract(1):Data Contract Overview
[原创]谈谈WCF中的Data Contract(2):WCF Data Contract对Generic的支持
[原创]谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持
[原创]谈谈WCF中的Data Contract(4):WCF Data Contract Versioning

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值