国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
WCF之旅(4):WCF中的序列化(Serialization)-

SOA 和Message

Windows Communication Foundation (WCF) 是基于面向服務(wù)架構(gòu)(Service Orientation Architecture——SOA)的一種理想的分布式技術(shù)(Distributed Technology), 相信在今后在建立基于SOA企業(yè)級別的解決方案和進行系統(tǒng)集成方面將會大有作為。一個基于SOA結(jié)構(gòu)的互聯(lián)系統(tǒng)(Connected System)通常由若干相互獨立的子系統(tǒng)(Sub-System)組成,這些子系統(tǒng)可能一個獨立的Application,也可能是由若干Application相互集成共同完成一組相關(guān)的任務(wù)的小系統(tǒng)。這些子系統(tǒng)以一種有效的方式組合、集成為我們聽過一種具有綜合功能的解決方案。

在一個基于SOA的分布式系統(tǒng)中,各個子系統(tǒng)相互獨立又相互關(guān)聯(lián)。說它們的相互獨立是因為他們各個都是一個個自治的系統(tǒng)(Autonomous System),可以實行各自的版本策略和部署策略,而這種版本的部署上的變動通常不應(yīng)該引起系統(tǒng)中其他部分的變動。說它們又彼此關(guān)聯(lián),則是因為一個子系統(tǒng)所需要的功能往往由其他某個子系統(tǒng)來實現(xiàn),我們把實現(xiàn)功能的一方稱為Service 的提供者(Provider),把使用Service的一方稱為客戶(Client)。Client依賴于Service的調(diào)用,而不失依賴于Service的實現(xiàn),只要Service的調(diào)用方式?jīng)]有發(fā)生改變,Service的實現(xiàn)變動對于Service的使用者來說是完全透明的。在WCF中,我們把Service的調(diào)用相關(guān)的提取出來即為我們經(jīng)常說的Contract,Service的提供者和Client之間共享的是Service Contract——而不傳統(tǒng)OO概念下的Type。把相對穩(wěn)定的Service Contract和經(jīng)常變動的Service Implementation相互分布早就了我們互聯(lián)系統(tǒng)的松耦合性(Loosely Couple)。

前面我們簡單介紹了SOA系統(tǒng)的基本特征——子系統(tǒng)之間的松耦合性(Loosely Couple);各個子系統(tǒng)的自治性(Autonomous);共享Contract。此外SOA還有其他的一些特征,最重要的一個特征就它是一個基于Message(Message-Based)的系統(tǒng)。子系統(tǒng)之間的相互交互由Message來實現(xiàn)。Client向Service的提供者發(fā)送一個Soap Message來訪為他所需要的Service,Service的提供者監(jiān)聽到來自Client的請求,創(chuàng)建相應(yīng)的Service對象,執(zhí)行相關(guān)的操作,把執(zhí)行的結(jié)果(Result)以Message 的形式發(fā)回給對應(yīng)的Client。所以我們可以說子系統(tǒng)之間的相互交互本質(zhì)上是一種消息的交互過程(Message Exchange)。不同的交互方式對應(yīng)不同的Message Exchange Pattern——MEP。

理解了SO的基本原理,我們來看看WCF,從WCF的全稱來分析——Windows Communication Foundation,顧名思義,他就是解決分布式互聯(lián)系統(tǒng)中各相互獨立的子系統(tǒng)如何交互的問題,換句話說,它實際上就是提供 一個基礎(chǔ)構(gòu)架(Infrastructure)實現(xiàn)Application的通信問題。我們前邊已經(jīng)提到,各個子系統(tǒng)之間是通過XML Message進行交互的,所以我們可以 把WCF看成是一個完全處理XML Message的構(gòu)架,WCF的所有的功能都是圍繞著Message來展開的——如何把一個Service的調(diào)用轉(zhuǎn)或稱一個Message Exchange(Service Contract);如何實現(xiàn)一般的.NET對象和能夠容納于XML Message中的XML Infoset之間的轉(zhuǎn)化(Serialization和Deserialization);如何實現(xiàn)承載數(shù)據(jù)的XML Infoset和能夠用于網(wǎng)絡(luò)傳遞的字節(jié)流(Byte Stream)之間的相互轉(zhuǎn)化(Encoding和Deconding);如何保證置于Message中數(shù)據(jù)的一致性和防止被惡意用戶竊取以及驗證調(diào)用Service和通過Service的合法性(Security:Confidentiality,Integrity,Authentication——CIA);如何保證Message被可靠地被傳達(dá)到所需的地方(Reliable Messaging);以及如何把若干次Service調(diào)用——本質(zhì)上是若干次Message Exchange納入到一個單獨的Conversation(Session Support 和Transaction Support……

在分布式系統(tǒng)中,一個Application與另一個Application之間進行交互,必然需要攜帶數(shù)據(jù)。前面我們說了,系統(tǒng)交互完全是應(yīng)Message的方式進行的,Message是XML,當(dāng)然置于Message中的數(shù)據(jù)也應(yīng)該是XML(XML Infoset)。如何處理這些交互的數(shù)據(jù),我們可能首先想到的就是直接處理XML,我們可以在XML級別通過相關(guān)的XML技術(shù)——XSD,XPath,XSLT來操作數(shù)據(jù)。但是要使我們處理后的XML需要和要求的完全一致,這樣的工作無疑是非??菰锓ξ抖屹M時費力的。而我們最擅長的就是使用.NET對象來封裝我們的數(shù)據(jù)。如何使我們創(chuàng)造的對象能夠有效地轉(zhuǎn)化成結(jié)構(gòu)化的XML Infoset,就是今天我們要講的內(nèi)容——Serialization。

Serialization V.S. Encoding

Serialization可以看成是把包含相同內(nèi)容的數(shù)據(jù)從一種結(jié)構(gòu) (.NET Object) 轉(zhuǎn)換成另一種結(jié)構(gòu) (XML) 。要實現(xiàn)在兩種不同結(jié)構(gòu)之間的轉(zhuǎn)化,這兩種結(jié)構(gòu)之間必須存在一種Mapping。Serialization的是實現(xiàn)由序列化器(Serializer)來負(fù)責(zé)。而Serializer則利用某種算法(Arithmetic)來提供這種Mapping。我們知道對于一個Managed Type的結(jié)構(gòu)信息——比如它的所有成員的列表,每個成員的Type、訪問限制,以及定在每個成員上的屬性,作為原數(shù)據(jù)被存貯在Assembly的原數(shù)據(jù)表中,這些原數(shù)據(jù)可以通過反射的機制獲得。而XML的結(jié)構(gòu)一般利用XSD來定義。所以 在WCF中的Serialization可以看成是Serializer通過反射的機制分析對象所對應(yīng)的Type的原數(shù)據(jù),從而提供一種算法實現(xiàn)Managed Type的XSD的轉(zhuǎn)化。

很多剛剛接觸WCF的人往往不能很好地區(qū)分Serialization和Encoding。我們的.NET Object通過Serialization轉(zhuǎn)化成XML Infoset。但是要使我們的數(shù)據(jù)能夠通過網(wǎng)絡(luò)協(xié)議在網(wǎng)絡(luò)上傳遞,必須把生成的XML Infoset轉(zhuǎn)化成字節(jié)流(Byte Stream)。所以Encoding關(guān)注的是XML Infoset到字節(jié)流(Byte Stream)這一段轉(zhuǎn)化的過程。在WCF中,有3中不同的方式可供選擇:Binary;Text和MTOM(Message Transmit Optimized Mechanism)。Binary具有最好的Performance,Text具有最好的互操作性,MTOM則有利于大量數(shù)據(jù)的傳送。

我們可以這樣來理解Serialization和Encoding,Sterilization是基于Service Contract的——而實際上它也是定義在Service Contract中,是放在我們的Code中;而Encoding一般由Binding提供,它是和Service無關(guān)的,我們一般在Configuration中根據(jù)實際的需要選擇我們合適的Encoding。WCF把Serialization和Encoding相互分離是有好處的,Serialization手部署環(huán)境的影響相對不大,具有相對的通用性,而Encoding則關(guān)系到訪問Service的性能以及互操作性等方面,和部署環(huán)境緊密相關(guān)。比如對于一個在一個Intranet內(nèi)部使用的系統(tǒng),往往處于提高Performance考慮,我們一般是使用TCP Transport結(jié)合Binary,可能在某一天出現(xiàn)的來自于Internet的潛在的調(diào)用,我們不得不改用Http作為Transport,并使用Text Encoding。由于Encoding是可配置的,所以在這種情況下,我們只需要改變Configuration文件就可以了。

DataContractSerializer

Serialization 是通過Serializer來完成的,在WCF中,我們有3種不同的Serializer——DataContractSerializer(定義在System.RunTime.Serializtion namespace中)、XMLSerializer(定義在System.XML.Serialization namespace)和NetDataContractSerializer (定義在System.XML.Serialization namespace) 。他們不同的方式實現(xiàn).NET Object的Serialization。由于DataContractSerializer和NetDataContractSerializer基本上沒有太大的區(qū)別,我們只討論DataContractSerializer和XMLSerializer。其中DataContractSerializer為WCF默認(rèn)的Serializer,如果沒有顯式定采用另外一種Serializer,WCF會創(chuàng)建一個DataContractSerializer 序列化NET Object。首先我們來討論DataContractSerializer采用怎樣的一種Mapping方式來把.NET Object轉(zhuǎn)化成XML。我們照例用實驗來說明問題。

我們創(chuàng)建兩個類DataContractProduct和DataContractOrder用于表示產(chǎn)品和訂單兩個實體,讀者完全可以命知道描述的內(nèi)容,這里不作特別的介紹。 

 

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

namespace Artech.WCFSerialization
{
    [DataContract]
    
public class DataContractProduct
    
{
        
Private Fields

        
Constructors

        
Properties

    }

}

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

namespace Artech.WCFSerialization
{
    [DataContract]
    [KnownType(
typeof(DataContractOrder))]
    
public class DataContractOrder
    
{
        
private Guid _orderID;
        
private DateTime _orderDate;
        
private DataContractProduct _product;
        
private int _quantity;

        
Constructors

        
Properties

        
public override string ToString()
        
{
            
return string.Format("ID: {0}\nDate:{1}\nProduct:\n\tID:{2}\n\tName:{3}\n\tProducing Area:{4}\n\tPrice:{5}\nQuantity:{6}",
                
this._orderID, this._orderDate, this._product.ProductID, this._product.ProductName, this._product.ProducingArea, this._product.UnitPrice, this._quantity);
        }

    }

}

使用DataContractSerializer序列化.NET Object。相關(guān)的Type必須運用System.Runtime.Serialization. DataContractAttribute, 需要序列化的成員必須運用System.Runtime.Serialization. DataMemberAttribute。為了使我們能夠了解DataContract默認(rèn)的Mapping機制,我們暫時不在DataContractAttribute和DataMemberAttribute設(shè)置任何參數(shù)。下面我們 來編寫具體的Serialization的代碼:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
using System.Diagnostics;

namespace Artech.WCFSerialization
{
    
class Program
    
{
        
static string _basePath = @"E:\Projects\Artech.WCFSerialization\Artech.WCFSerialization\";

        
static void Main(string[] args)
        
{
            SerializeViaDataContractSerializer();
        }

        
static void SerializeViaDataContractSerializer()
        
{
            DataContractProduct product 
= new DataContractProduct(Guid.NewGuid(), "Dell PC""Xiamen FuJian"4500);
            DataContractOrder order 
= new DataContractOrder(Guid.NewGuid(), DateTime.Today, product, 300);
            
string fileName = _basePath + "Order.DataContractSerializer.xml";
            
using (FileStream fs = new FileStream(fileName, FileMode.Create))
            
{
                DataContractSerializer serializer 
= new DataContractSerializer(typeof(DataContractOrder));
                
using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(fs))
                
{
                    serializer.WriteObject(writer, order);
                }

            }

            Process.Start(fileName);
        }

    }

}

代碼很簡單,這里不作特別介紹。我們現(xiàn)在只關(guān)心生成XML是怎樣的結(jié)構(gòu): 

這里我們總結(jié)出以下的Mapping關(guān)系:

1.        Root Element為對象的Type Name——DataContractOrder

2.        Type的Namespace會被加到XML根節(jié)點的Namespace中http://schemas.datacontract.org/2004/07/Artech.WCFSerialization

3.        對象的所有成員以XML Element的形式而不是以XML Attribute的形式輸出。

4.        所以對象在XML的輸出順序是按照字母排序。

5.        所有成員的Elelement 名稱為成員名稱。

6.        不論成員設(shè)置怎樣的作用域(public,protected,internal,甚至市Private),

所有運用了DataMemberAttribute的成員均被序列化到XML中——private string ProducingArea。

7.        Type和成員必須運用DataContractAttribute和DataMemberAttribute才能被序列化。

 

上面這些都是默認(rèn)的Mapping關(guān)系,在通常情況下我們用默認(rèn)的這種Mapping往往不能滿足我們的需求,為了把.NET序列化成我們需要的XML 結(jié)構(gòu)(比如我們的XmL必須于我們預(yù)先定義的XSD一致),我們可以在這兩個Attribute(DataContractAttribute和DataMemberAttribute)制定相關(guān)的參數(shù)來實現(xiàn)。具體做法如下。

 

1.        Root Element可以通過DataContractAttribute中的Name參數(shù)定義。

2.        Namespace可以通過DataContractAttribute中的NameSpace參數(shù)定義。

3.        對象的成員只能以XML Element的形式被序列化。

4.        對象成員對應(yīng)的XML Element在XML出現(xiàn)的位置可以通過DataMemberAttribute的Order參數(shù)來定義。

5.        對象成員對應(yīng)的Element的名稱可以通過DataMemberAttribute中的Name定義。

6.        如果不希望某個成員輸出到XML中,可以去掉成員對應(yīng)的DataMemberAttribute Attribute。

此外DataMemberAttribute還有連個額外的參數(shù):

1.         IsRequired:制定該成員為必須的,如果通過工具生成XSD的話,對應(yīng)的Element的minOccur=“1”

2.        EmitDefaultValue:制定是否輸入沒有賦值的成員(值為默認(rèn)值)是否出現(xiàn)在XML中。

基于上面這些,現(xiàn)在我們修改我們的DataContractOrder和DataContractProduct。

 

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

namespace Artech.WCFSerialization
{
    [DataContract(Name 
= "product", Namespace = "http://Artech.WCFSerialization/Samples/Product")]
    
public class DataContractProduct
    
{
        
Private Fields

        
Constructors

        
Properties

    }

}

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

namespace Artech.WCFSerialization
{
    [DataContract(Name 
="order",Namespace="http://Artech.WCFSerialization/Samples/Order")]
    
public class DataContractOrder
    
{
        
private Guid _orderID;
        
private DateTime _orderDate;
        
private DataContractProduct _product;
        
private int _quantity;

        
Constructors

        
Properties

        
public override string ToString()
        
{
            
return string.Format("ID: {0}\nDate:{1}\nProduct:\n\tID:{2}\n\tName:{3}\n\tProducing Area:{4}\n\tPrice:{5}\nQuantity:{6}",
                
this._orderID, this._orderDate, this._product.ProductID, this._product.ProductName, this._product.ProducingArea, this._product.UnitPrice, this._quantity);
        }

    }

}

再次進行序列化,看看得到的XML是什么樣子?

<order xmlns="http://Artech.WCFSerialization/Samples/Order" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  
<id>994b42c4-7767-4ed4-bdf8-033e99c00a64</id>
  
<date>2007-03-09T00:00:00+08:00</date>
  
<product xmlns:a="http://Artech.WCFSerialization/Samples/Product">
    
<a:id>137e6c34-3758-413e-8f8a-83f26f78a174</a:id>
    
<a:name>Dell PC</a:name>
    
<a:producingArea>Xiamen FuJian</a:producingArea>
    
<a:price>4500</a:price>
  
</product>
  
<quantity>300</quantity>
</order>

注:對于DataContract Serializer,這里有兩點需要我們注意的:

1.         由于Serialization是對數(shù)據(jù)的不同結(jié)構(gòu)或形態(tài)的轉(zhuǎn)化,在轉(zhuǎn)化過程中必須預(yù)先知道兩種數(shù)據(jù)相關(guān)的原數(shù)據(jù)(Metadata)。而對于每個.NET對象來說,它的數(shù)據(jù)結(jié)果存放在他所對應(yīng)的Assembly的原數(shù)據(jù)表中(Metadata Table),這些原數(shù)據(jù)表定義的每個定義在該Assembly中的Type的成員定義——包括成員的Type,訪問作用域,成員名稱,以及運用在成員上的所有Attribute。原則上,只要知道.NET對象對應(yīng)的Type,我們就可以通過反射(Reflection)的機制分析出該對象的結(jié)構(gòu)。在該例子中,Serializer要序列化DataContractOrder的對象,必須首先知道該對象所屬的Type——這個Type通過構(gòu)造函數(shù)傳遞給Serializer。但是DataContractOrder定義了一個特殊的成員Product,他屬于我們的自定義Type:DataContractProduct(這里需要特別指出的是對于.NET的基元類型——Primary Type和一半的常用Type——比如DateTime,Guid等等,Serializer可以自動識別,所以不用特別指定),Serializer是不會識別這個對象的,所以我們需要在定義DataContractOrder的時候運用KnownType Attribute來這個Type。

2.         因為在傳統(tǒng)的分布式應(yīng)用中,我們廣泛地采用Serializable Attribute來表明該對象是可以序列化的,DataContract Serializer對這種機制也是支持的。

上面我們講了Serialization,它的本質(zhì)就是把.NETObject轉(zhuǎn)化具有一定結(jié)構(gòu)的XML Infoset。被序列化的成的XML Infoset記過Encoding被進一步轉(zhuǎn)化成適合在網(wǎng)絡(luò)上傳遞的字節(jié)流。當(dāng)這些字節(jié)流從一個Application傳遞到另一個Application,由于我們的程序的業(yè)務(wù)邏輯處理的是一個個的.NET對象,所以在目標(biāo)Application, 會以一個相反的過程把接收到的字節(jié)流重構(gòu)成為和原來一樣的.NET Object——目標(biāo)Application對接收到的字節(jié)流記過Decoding轉(zhuǎn)化成XML Infoset,然后通過創(chuàng)建和用于序列化過程一致的Serializer通過Deserialization重建一個.NET Object。所以這就對Serializer提出了要求——它必須為Managed Type的結(jié)構(gòu)和XML的結(jié)構(gòu)提供可逆性的保證——我們把一個.NET Object序列化成一組XML,然后對這組XML進行反序列化重建的對象必須和原來一致。

現(xiàn)在我們在驗證這種一致性。在上面的Sample中,我們創(chuàng)建了一個DataContractOrder對象,對它進行序列化并把生成的XML保存的一個文件里面(Order.DataContractSerializer.xml),現(xiàn)在我們都讀取這個文件的內(nèi)容,把它反序列化成DataContractOrder 對象,看它的內(nèi)容是否和原來一樣。下面是Deserialization的邏輯。

static void DeserializeViaDataContractSerializer()
        
{
            
string fileName = _basePath + "Order.DataContractSerializer.xml";
            DataContractOrder order;
            
using (FileStream fs = new FileStream(fileName, FileMode.Open))
            
{
                DataContractSerializer serializer 
= new DataContractSerializer(typeof(DataContractOrder));
                
using (XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas()))
                
{
                    order 
= serializer.ReadObject(reader) as DataContractOrder;
                }

            }


            Console.WriteLine(order);
            Console.Read();
        }
調(diào)用這個方法,通過在控制臺輸出DataContractOrder的內(nèi)容,我們可以確定,通過Deserialization生成的DataContractOrder 對象和原來的對象具有一樣的內(nèi)容。

XMLSerializer

提到XMLSerializer,我想絕大多數(shù)人都知道這是asmx采用的Serializer。首先我們還是來看一個例子,通過比較Managed Type的結(jié)構(gòu)和生成的XML的結(jié)構(gòu)來總結(jié)這種序列化方式采用的是怎樣的一種Mapping方式。和DataContractSerialzer Sample一樣,我們要定義用于序列化對象所屬的Type——XMLOrder和XMLProduct,他們和相面對應(yīng)的DataContractOrder和DataContractProduct具有相同的成員。

using System;
using System.Collections.Generic;
using System.Text;
360docimg_501_
360docimg_502_
namespace Artech.WCFSerialization
360docimg_503_360docimg_504_
{
360docimg_506_    
public class XMLProduct
360docimg_507_360docimg_508_    
{
360docimg_510_360docimg_511_        
Private Fields

360docimg_591_}

360docimg_592_


360docimg_593_using System;
360docimg_594_
using System.Collections.Generic;
360docimg_595_
using System.Text;
360docimg_596_
360docimg_597_
namespace Artech.WCFSerialization
360docimg_598_360docimg_599_
{
360docimg_601_    
public class XMLOrder
360docimg_602_360docimg_603_    
{
360docimg_605_        
private Guid _orderID;
360docimg_606_        
private DateTime _orderDate;
360docimg_607_        
private XMLProduct _product;
360docimg_608_        
private int _quantity;
360docimg_609_
360docimg_610_360docimg_611_        
Constructors
360docimg_633_
360docimg_634_360docimg_635_        
Properties
360docimg_684_
360docimg_685_        
public override string ToString()
360docimg_686_360docimg_687_        
{
360docimg_689_            
return string.Format("ID: {0}\nDate:{1}\nProduct:\n\tID:{2}\n\tName:{3}\n\tProducing Area:{4}\n\tPrice:{5}\nQuantity:{6}",
360docimg_690_                
this._orderID,this._orderDate,this._product.ProductID,this._product.ProductName,this._product.ProducingArea,this._product.UnitPrice,this._quantity);
360docimg_691_        }

360docimg_692_    }

360docimg_693_}

360docimg_694_

編寫Serialization的Code.

360docimg_695_360docimg_696_

調(diào)用上面定義的方法,生成序列化的XML。

360docimg_719_<?xml version="1.0" encoding="utf-8"?>
360docimg_720_
<XMLOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
360docimg_721_    
<OrderID>b695fd18-9cd7-4792-968a-0c0c3a3962c2</OrderID>
360docimg_722_    
<OrderDate>2007-03-09T00:00:00+08:00</OrderDate>
360docimg_723_    
<Product>
360docimg_724_        
<ProductID>23a2fe03-d0a0-4ce5-b213-c7e5196af566</ProductID>
360docimg_725_        
<ProductName>Dell PC</ProductName>
360docimg_726_        
<UnitPrice>4500</UnitPrice>
360docimg_727_    
</Product>
360docimg_728_    
<Quantity>300</Quantity>
360docimg_729_
</XMLOrder>
360docimg_730_

這里我們總結(jié)出以下的Mapping關(guān)系:

  1. Root Element被指定為類名。
  2. 不會再Root Element中添加相應(yīng)的Namaspace。
  3. 對象成員以XML Element的形式輸出。
  4. 對象成員出現(xiàn)的順利和在Type定義的順序一致。
  5. 只有Public Field和可讀可寫得Proppery才會被序列化到XML中——比如定義在XMLProduct中的internal string ProducingArea沒有出現(xiàn)在XML中。
  6. Type定義的時候不需要運用任何Attribute。

以上這些都是默認(rèn)的Mapping關(guān)系,同DataContractSerializer一樣,我們可以通過在Type以及它的成員中運用一些Attribute來改這種默認(rèn)的Mapping。

  1. Root Element名稱之后能為類名。
  2. 可以在Type上運用XMLRoot,通過Namaspace參數(shù)在Root Element指定Namespace。
  3. 可以通過在類成員上運用XMLElement Attribute和XMLAttribute Attribute指定對象成員轉(zhuǎn)化成XMLElement還是XMLAttribute。并且可以通過NameSpace參數(shù)定義Namespace。
  4. 可以在XMLElement或者XMLAttribute Attribute 通過Order參數(shù)指定成員在XML出現(xiàn)的位置。
  5. 可以通過XmlIgnore attribute阻止對象成員被序列化。

基于上面這些,我們重新定義了XMLProduct和XMLOrder。

360docimg_731_using System;
360docimg_732_
using System.Collections.Generic;
360docimg_733_
using System.Text;
360docimg_734_
using System.Xml.Serialization;
360docimg_735_
360docimg_736_
namespace Artech.WCFSerialization
360docimg_737_360docimg_738_
{
360docimg_740_    
public class XMLProduct
360docimg_741_360docimg_742_    
{
360docimg_744_360docimg_745_        
Private Fields
360docimg_751_
360docimg_752_360docimg_753_        
Constructors
360docimg_772_
360docimg_773_360docimg_774_        
Properties
360docimg_827_
360docimg_828_    }

360docimg_829_}

360docimg_830_

360docimg_831_using System;
360docimg_832_
using System.Collections.Generic;
360docimg_833_
using System.Text;
360docimg_834_
using System.Xml.Serialization;
360docimg_835_
360docimg_836_
namespace Artech.WCFSerialization
360docimg_837_360docimg_838_
{
360docimg_840_    [XmlRoot(Namespace 
= "http://artech.wcfSerialization/Samples/Order")]
360docimg_841_    
public class XMLOrder
360docimg_842_360docimg_843_    
{
360docimg_845_        
private Guid _orderID;
360docimg_846_        
private DateTime _orderDate;
360docimg_847_        
private XMLProduct _product;
360docimg_848_        
private int _quantity;
360docimg_849_
360docimg_850_360docimg_851_        
Constructors
360docimg_873_
360docimg_874_360docimg_875_        
Properties
360docimg_926_
360docimg_927_        
public override string ToString()
360docimg_928_360docimg_929_        
{
360docimg_931_            
return string.Format("ID: {0}\nDate:{1}\nProduct:\n\tID:{2}\n\tName:{3}\n\tProducing Area:{4}\n\tPrice:{5}\nQuantity:{6}",
360docimg_932_                
this._orderID,this._orderDate,this._product.ProductID,this._product.ProductName,this._product.ProducingArea,this._product.UnitPrice,this._quantity);
360docimg_933_        }

360docimg_934_    }

360docimg_935_}

360docimg_936_

 

重新進行一次Serialization。我們可以得到下面的XML。

360docimg_937_<?xml version="1.0" encoding="utf-8"?>
360docimg_938_
<XMLOrder id="9a0bbda4-1743-4398-bc4f-ee216e02695b" xmlns="http://artech.wcfSerialization/Samples/Order" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
360docimg_939_  
<product id="4e3aabe5-3a51-4000-9fd8-d821d164572a" xmlns="Http://Artech.WCFSerialization/Samples/Product">
360docimg_940_    
<name>Dell PC</name>
360docimg_941_    
<producingArea>Xiamen FuJian</producingArea>
360docimg_942_    
<price>4500</price>
360docimg_943_  
</product>
360docimg_944_  
<quantity>300</quantity>
360docimg_945_  
<date>2007-03-09T00:00:00+08:00</date>
360docimg_946_
</XMLOrder>
360docimg_947_

分析完XMLSerializer的Serialization功能,我們照例來分析它的反向過程—Deserialization。下面的Deserialization的Code。

360docimg_948_360docimg_949_

調(diào)用DeserializeViaXMLSerializer,得到下面的Screen Shot。下面顯示的Order對象的信息和我們利用DataContractSerializaer進行Deserialization是的輸出沒有什么兩樣。不過有趣的是上面多出了兩行額外的輸出:The constructor of XMLProduct has been invocated! The constructor of XMLOrder has been invocated。而這個操作實際上是定義在XMLProduct和XMLOrder的默認(rèn)(無參)構(gòu)造函數(shù)里的。所此我們可以得出這樣的結(jié)論——用XMLSerializer進程Deserialization,會調(diào)用的默認(rèn)(無參)構(gòu)造函數(shù)來初始化對象。 
360docimg_973_

DataContractSerializer V.S. XMLSerializer

上面我們分別分析了兩種不同的Serializer,現(xiàn)在我們來簡單總結(jié)一下他們的區(qū)別:

特性

XMLSerializer

DataContractSerializer

默認(rèn)Mapping

所有Public Field和可讀可寫Property

所有DataMember Filed、Property

是否需要Attribute

不需要

DataContract DataMember或者Serializable

成員的默認(rèn)次序

Type中定義的順序

字母排序

兼容性

.asmx

Remoting

Deserialzation

調(diào)用默認(rèn)構(gòu)造函數(shù)

不會調(diào)用


本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
如何使用SQLSERVER2000中的XML功能
【ASP.NET Core學(xué)習(xí)】Web API
AXIS開始Web 服務(wù)
SQL Server DATEADD() 函數(shù)
MySQL NOW() 函數(shù)
sql查詢基本語法
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服