WCF序列化各種方式詳解
WCF是一款由微軟公司開發(fā)的一款功能強(qiáng)大的工具,可以為開發(fā)人員輕松的創(chuàng)建一個(gè)安全性較高的解決方案。在這里我們就先為大家詳細(xì)介紹一下有關(guān)WCF序列化的相關(guān)概念,希望能給大家?guī)?lái)一些幫助。
大家知道,WCF內(nèi)置了兩種序列化方式,DataContractSerializer和NetDataContractSerializer。WCF序列化的基本概念A(yù)rtech兄已經(jīng)說(shuō)得很清楚了,在此不再贅述,本文僅就此二者的區(qū)別作一番探討。
先來(lái)看看兩者的聲明:
- public sealed class DataContractSerializer : XmlObjectSerializer
- {
- public DataContractSerializer(Type type);
- … public override object ReadObject(XmlReader reader);
- public object ReadObject(Stream stream);
- public void WriteObject(Stream stream, object graph);
- public override void WriteObject(XmlWriter writer, object graph); …
- }
- public sealed class NetDataContractSerializer :
XmlObjectSerializer, IFormatter- {
- public NetDataContractSerializer();
- … public object Deserialize(Stream stream);
- public void Serialize(Stream stream, object graph);
- public override object ReadObject(XmlReader reader);
- public object ReadObject(Stream stream);
- public void WriteObject(Stream stream, object graph);
- public override void WriteObject(XmlWriter writer, object graph);
- …}
其中兩者的ReadObject(Straem)、WriteObject(Stream, object)的實(shí)現(xiàn)繼承自基類XmlObjectSerializer,其他方法均為已覆寫或?qū)崿F(xiàn)。 #t#
從兩個(gè)類型的聲明中可以看出NetDataContractSerializer實(shí)現(xiàn)了IFormatter接口,而DataContractSerializer沒有,因此只有NetDataContractSerializer能使用.NET基礎(chǔ)結(jié)構(gòu)中的序列化,而DataContractSerializer則是專用于WCF的。
還有一個(gè)細(xì)節(jié)DataContractSerializer的Constructor有一個(gè)Type類型的參數(shù),而NetDataContractSerializer沒有。這可蘊(yùn)藏著深意啊,讀者接著看就明白了。
現(xiàn)在,再來(lái)看看此二者的最大關(guān)鍵區(qū)別吧!從一個(gè)WCF序列化示例開始吧:
- [DataContract]
- public class Sub
- {
- // Fields [DataMember]
- public int Id;
- [DataMember]
- public string Name;
- // Methods
- public Sub() {}
- public Sub(int id, string name) {
- this.Id = id; this.Name = name;
- }}
以上是一個(gè)再簡(jiǎn)單不過(guò)的DataContract的,把他給序列化看看出來(lái)些啥。
先用DataContractSerializer序列化:
- Sub sub = new Sub(9, "nine");
- DataContractSerializer dcs = new DataContractSerializer(typeof(Sub));
- MemoryStream stream = new MemoryStream();
- dcs.WriteObject(stream, sub);
- byte[] buf = stream.ToArray();
- string str = Encoding.UTF8.GetString(buf, 0, buf.Length);
執(zhí)行完以上代碼后,str的值為:
- < Sub xmlns="http://schemas.datacontract.org/2004/07/
ServiceInterface" xmlns:i="http://www.w3.org/2001/
XMLSchema-instance">- < Id>10< /Id>
- < Name>nine< /Name>
- < /Sub>
恩,此SOAP消息那是相當(dāng)?shù)谜?。然后將同一個(gè)對(duì)象用NetDataContractSerializer序列化:
- NetDataContractSerializer ndcs = new NetDataContractSerializer();
- MemoryStream nstream = new MemoryStream();
- ndcs.WriteObject(nstream, sub);
- byte[] nbuf = nstream.ToArray();
- string nstr = Encoding.UTF8.GetString(nbuf, 0, nbuf.Length);
觀察一下nstr的值:
- < Sub z:Id="1" z:Type="ServiceInterface.Sub" z:Assembly=
"ServiceInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
xmlns="http://schemas.datacontract.org/2004/07/ServiceInterface"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">- < Id>10< /Id>
- < Name z:Id="2">nine< /Name>
- < /Sub>
發(fā)現(xiàn)了嗎?撇開xml命名空間不說(shuō),Sub元素多了Type,Assembly和Id,Name屬性也多了個(gè)Id。信息完整多了~~,現(xiàn)在就可以解釋兩者Constructor的區(qū)別了,DataContractSerializer是按照SOA的datacontract協(xié)議(與SOAP基本一直)來(lái)序列化對(duì)象的,它并不包含平臺(tái)相關(guān)的信息,比如類型,程序集等。所以比如在創(chuàng)建序列化器時(shí)就提供將要序列化和反系列化的類型信息,DataContractSerializer無(wú)法工作。而NetDataContractSerializer則大大擴(kuò)充了SOAP,為它添加了程序集、類型名等附加信息,這樣一來(lái),序列化器可以完全由序列化的內(nèi)容來(lái)準(zhǔn)確推斷將要構(gòu)造的對(duì)象,而不必依賴Constructor所提供的類型參數(shù)了。這就是兩者Constructor不同的原因。
以上就是對(duì)WCF序列化的相關(guān)介紹。