<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      我的WCF之旅(4):WCF中的序列化[上篇]

      SOA 和Message

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

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

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

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

      在分布式系統中,一個Application與另一個Application之間進行交互,必然需要攜帶數據。前面我們說了,系統交互完全是應Message的方式進行的,Message是XML,當然置于Message中的數據也應該是XML(XML Infoset)。如何處理這些交互的數據,我們可能首先想到的就是直接處理XML,我們可以在XML級別通過相關的XML技術——XSD,XPath,XSLT來操作數據。但是要使我們處理后的XML需要和要求的完全一致,這樣的工作無疑是非常枯燥乏味而且費時費力的。而我們最擅長的就是使用.NET對象來封裝我們的數據。如何使我們創造的對象能夠有效地轉化成結構化的XML Infoset,就是今天我們要講的內容——Serialization。

      Serialization V.S. Encoding

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

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

      我們可以這樣來理解Serialization和Encoding,Sterilization是基于Service Contract的——而實際上它也是定義在Service Contract中,是放在我們的Code中;而Encoding一般由Binding提供,它是和Service無關的,我們一般在Configuration中根據實際的需要選擇我們合適的Encoding。WCF把Serialization和Encoding相互分離是有好處的,Serialization手部署環境的影響相對不大,具有相對的通用性,而Encoding則關系到訪問Service的性能以及互操作性等方面,和部署環境緊密相關。比如對于一個在一個Intranet內部使用的系統,往往處于提高Performance考慮,我們一般是使用TCP Transport結合Binary,可能在某一天出現的來自于Internet的潛在的調用,我們不得不改用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) 。他們不同的方式實現.NET Object的Serialization。由于DataContractSerializer和NetDataContractSerializer基本上沒有太大的區別,我們只討論DataContractSerializer和XMLSerializer。其中DataContractSerializer為WCF默認的Serializer,如果沒有顯式定采用另外一種Serializer,WCF會創建一個DataContractSerializer 序列化NET Object。首先我們來討論DataContractSerializer采用怎樣的一種Mapping方式來把.NET Object轉化成XML。我們照例用實驗來說明問題。

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

       

      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。相關的Type必須運用System.Runtime.Serialization. DataContractAttribute, 需要序列化的成員必須運用System.Runtime.Serialization. DataMemberAttribute。為了使我們能夠了解DataContract默認的Mapping機制,我們暫時不在DataContractAttribute和DataMemberAttribute設置任何參數。下面我們 來編寫具體的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);
              }

          }

      }

      代碼很簡單,這里不作特別介紹。我們現在只關心生成XML是怎樣的結構: 

      這里我們總結出以下的Mapping關系:

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

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

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

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

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

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

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

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

       

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

       

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

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

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

      4.        對象成員對應的XML Element在XML出現的位置可以通過DataMemberAttribute的Order參數來定義。

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

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

      此外DataMemberAttribute還有連個額外的參數:

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

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

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

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

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

      現在我們在驗證這種一致性。在上面的Sample中,我們創建了一個DataContractOrder對象,對它進行序列化并把生成的XML保存的一個文件里面(Order.DataContractSerializer.xml),現在我們都讀取這個文件的內容,把它反序列化成DataContractOrder 對象,看它的內容是否和原來一樣。下面是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();
              }

      調用這個方法,通過在控制臺輸出DataContractOrder的內容,我們可以確定,通過Deserialization生成的DataContractOrder 對象和原來的對象具有一樣的內容。

       通過這里進入Part II。


      WCF相關內容:
      [原創]我的WCF之旅(1):創建一個簡單的WCF程序
      [原創]我的WCF之旅(2):Endpoint Overview
      [原創]我的WCF之旅(3):在WCF中實現雙向通信(Bi-directional Communication)
      [原創]我的WCF之旅(4):WCF中的序列化(Serialization)- Part I
      [原創]我的WCF之旅(4):WCF中的序列化(Serialization)- Part II
      [原創]我的WCF之旅(5):Service Contract中的重載(Overloading)
      [原創]我的WCF之旅(6):在Winform Application中調用Duplex Service出現TimeoutException的原因和解決方案
      [原創]我的WCF之旅(7):面向服務架構(SOA)和面向對象編程(OOP)的結合——如何實現Service Contract的繼承
      [原創]我的WCF之旅(8):WCF中的Session和Instancing Management
      [原創]我的WCF之旅(9):如何在WCF中使用tcpTrace來進行Soap Trace
      [原創]我的WCF之旅(10): 如何在WCF進行Exception Handling
      [原創]我的WCF之旅(11):再談WCF的雙向通訊-基于Http的雙向通訊 V.S. 基于TCP的雙向通訊

      [原創]我的WCF之旅(12):使用MSMQ進行Reliable Messaging
      [原創]我的WCF之旅(13):創建基于MSMQ的Responsive Service

      posted @ 2007-03-10 00:33  Artech  閱讀(49382)  評論(71)    收藏  舉報
      主站蜘蛛池模板: 国产美女自慰在线观看| 亚洲国产精品第一二三区| 国内精品一区二区在线观看| 人妻日韩精品中文字幕| 亚洲精品综合网中文字幕| 性欧美vr高清极品| 国产三级精品三级在专区| 欧美日韩中文字幕视频不卡一二区| 亚洲一区二区av高清| 亚洲国产韩国欧美在线| 四虎永久免费高清视频| 日日爽日日操| 婷婷综合久久中文字幕| 精品人妻中文字幕av| 青春草在线视频观看| 成人3D动漫一区二区三区| 伊人大杳焦在线| 国产又爽又黄又刺激的视频| 中文字幕人妻精品在线| 狠狠婷婷综合久久久久久| 国产九九视频一区二区三区 | 华人在线亚洲欧美精品| 亚洲熟妇色自偷自拍另类| 亚洲这里只有久热精品伊人 | 漂亮人妻中文字幕丝袜| 国内熟妇人妻色在线视频| 亚洲色大成网站www久久九九| 国产999精品2卡3卡4卡| 91人妻熟妇在线视频| 国产成人 综合 亚洲欧洲 | 97久久超碰精品视觉盛宴| 亚洲欧洲一区二区精品| 崇信县| 体态丰腴的微胖熟女的特征| 男女爽爽无遮挡午夜视频| 国产精品久久久天天影视| 久久亚洲国产精品五月天| 丁香婷婷激情俺也去俺来也| 潢川县| 国产精品户外野外| 成人免费无遮挡在线播放|