WCF傳輸數(shù)據(jù)應(yīng)用技巧剖析
WCF是建立在.Net Framework 2.0基礎(chǔ)之上的,它的應(yīng)用可以幫助開發(fā)人員帶來(lái)很多功能。在這里我們將會(huì)為大家詳細(xì)介紹一下有關(guān)WCF傳輸數(shù)據(jù)的相關(guān)方法,以此來(lái)方便大家理解這方面的應(yīng)用。
最近的開發(fā),一直被DataContract頭疼,微軟為了更好的通用性和代碼無(wú)關(guān)性,將DataContract進(jìn)行了一系列的優(yōu)化,使作為DataContract的類在進(jìn)行Serialize的時(shí)候會(huì)被序列化成非常通用的數(shù)據(jù)格式,可以在任何開發(fā)語(yǔ)言中調(diào)用。但是我們是僅僅使用C#進(jìn)行客戶端和服務(wù)器端的開發(fā),而且客戶端和服務(wù)器端交換的數(shù)據(jù)是同一個(gè)類型。
剛開始我的代碼是這樣寫的:
- using System;
- using System.Collections;
- using System.ServiceModel;
- using System.Runtime.Serialization;
- namespace JCDEV.WCF.Test1
- {
- [DataContract]
- public class Message
- {
- private DataCommandCollections list;
- [DataMember]
- public DataCommandCollections List
- {
- get { return list; }
- set { list = value; }
- }
- }
- [DataContract]
- public class DataCommandCollections : CollectionBase
- {
- [DataMember]
- public IList List
- {
- get
- {
- return base.InnerList;
- }
- }
- }
- [DataContract]
- public class DataCommand
- {
- //代碼省略...
- }
- }
我的本意是傳遞Message類,類中包含一個(gè)DataCommand的數(shù)組,但是這樣做的結(jié)果是,生成的客戶端代碼中DataCommandCollections被修正為了一個(gè)object[],而DataCommand未被序列化。我總結(jié)一下原因是:DataCommandCollections集成于CollectionBase,該類是一個(gè)Collection的基類,內(nèi)部有一個(gè)ArrayList數(shù)組,該數(shù)組默認(rèn)是實(shí)現(xiàn)IList接口的,內(nèi)部數(shù)據(jù)是Object型,所以在序列化是就生成了Object[],而不管實(shí)際的內(nèi)部數(shù)據(jù)是何類型。
到這里我分析,DataContract在客戶端生成代碼時(shí)是根據(jù)其內(nèi)部參數(shù)的類型來(lái)決定的。因此數(shù)組必須顯性設(shè)置為DataCommand的數(shù)組,否則都將無(wú)法生成正確的代碼。
解決該問(wèn)題的方法是使用List<T>來(lái)作為父類,該類通過(guò)泛型的方式指定其內(nèi)部參數(shù),下面是我改進(jìn)的程序:
- using System;
- using System.Collections;
- using System.ServiceModel;
- using System.Runtime.Serialization;
- using System.Collections.Generic;
- namespace JCDEV.WCF.Test1
- {
- [DataContract]
- public class Message
- {
- private DataCommandCollections list;
- [DataMember]
- public DataCommandCollections List
- {
- get { return list; }
- set { list = value; }
- }
- }
- [DataContract]
- public class DataCommandCollections :List<DataCommand>
- {
- //代碼省略...
- }
- [DataContract]
- public class DataCommand
- {
- //代碼省略...
- }
- }
程序改進(jìn)后在生成客戶端時(shí)出錯(cuò),查了下原因是因?yàn)槿绻悓?shí)現(xiàn)了IEnumable接口時(shí),.Net會(huì)默認(rèn)將他作為一個(gè)Collections類來(lái)進(jìn)行序列化,無(wú)需指定他為DataContract,如果需自定義,應(yīng)該使用CollectionDataContract特性。將代碼修改后就沒有錯(cuò)誤了??蛻舳苏_的生成了一個(gè)DataCommand[]和DataCommand類。#t#
但是這樣生成的客戶端代碼其實(shí)并沒有什么用,因?yàn)榭蛻舳吮緛?lái)就可以直接調(diào)用Message類,后來(lái)一個(gè)偶然的機(jī)會(huì),我發(fā)現(xiàn)了一個(gè)新的方法,就是在客戶端添加服務(wù)引用時(shí),選擇高級(jí),然后將重新使用引用的程序集中的類型勾選上,這樣客戶端就不會(huì)生成一個(gè)Message類,而是直接使用自己引用的Message類了。
這里也可以設(shè)置對(duì)于集合類型,在客戶端解析后的生成方式,默認(rèn)是生成一個(gè)數(shù)組。
這里要注意一點(diǎn),當(dāng)使用重引用選項(xiàng)后,DataContract將無(wú)法使用,出的錯(cuò)誤是“類型未被標(biāo)示為可序列化”,我是使用Serializable來(lái)代替的,這個(gè)原因是什么我還不清楚,如果有人知道,希望也告訴我一下,謝謝。
補(bǔ)充一下:“類型未被標(biāo)示為可序列化”原因找到了,是我疏忽的錯(cuò)誤,呵呵,原因是我有一個(gè)對(duì)Message類進(jìn)行序列化的函數(shù),程序時(shí)在這里提示的錯(cuò)誤。DataContract是可以使用的。至于.Net如何對(duì)集合進(jìn)行操作,我將稍候發(fā)布。