WCF初探-23:WCF中使用Message類(下)


前言

 

  • 在上一篇WCF中使用Message()中,文章介紹了WCF中使用Message類的基本知識和怎樣創建消息,本文是承接上一篇文章,如果想要更好的閱讀本文,請先閱讀上一篇文章。在這篇文章中,我將介紹怎樣來操作消息。
  • WCF中使用Message()中,我們知道了消息的基本結構,針對不同的情況,我們對消息進行了創建。在創建消息后,我們還可以對消息進行寫入、讀取、復制等操作,以便我們在不同的任務環境下更好的運用消息傳輸機制。

 

通過Message類提取消息正文的幾種方式

 

  • Message 類支持多種從其正文提取信息的方式。它們可分為以下幾類:
  1. 將整個消息正文一次性寫出到 XML 編寫器。這稱為“寫入消息”。
  2. 將 XML 讀取器放在消息正文上。這使您可以在以后根據需要逐段訪問消息正文。這稱為“讀取消息”。
  3. 可以將整個消息(包括它的正文)復制到類型為 MessageBuffer 的內存中緩沖區。這稱為“復制消息”。
  • 注意:無論使用哪種訪問方式,都只能訪問 Message 的正文一次。消息對象具有 State 屬性,該屬性最初設置為 Created。前面列表中描述的三種訪問方法分別將狀態設置為 Written、Read 和 Copied。此外,Close 方法可以在不再需要消息正文內容時將狀態設置為 Closed。只有當消息正文處於 Created 狀態時,才能對其進行訪問,並且在狀態已更改后,無法返回到 Created 狀態。

 

寫入消息

 

  • Message類為我們提供了幾種寫入消息的方法
  1. WriteBodyContents 方法:將給定 Message 實例的正文內容寫出到給定 XML 編寫器
  2. WriteBody 方法:執行相同的操作,不同之處在於該方法將正文內容封裝在適當的包裝元素(如 <soap:body>)中。
  3. WriteMessage方法:寫出整個消息,包括 SOAP 包裝信封和標頭。如果禁用 SOAP(Version 為 MessageVersion.None),則所有這三個方法都執行相同的操作:寫出消息正文內容。
  • 注意:本文采用的示例為WCF中使用Message()中所使用的示例,源碼已經在文章底部的評論區給出,下載后,我們可以根據本文的操作完善代碼,驗證我們對消息的操作。本文的源碼也已經在文章底部的評論區給出。
  • 我們可以分別采用Message類不同的操作方法類寫入消息結構。參考代碼如下:
        //寫入消息
        Message message = proxy.GetDataXml();
        FileStream stream = new FileStream(@"c:/log.xml", FileMode.Create);
        XmlDictionaryWriter xdr = XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8);
        message.WriteBodyContents(xdr);
        //message.WriteBody(xdr);
        //message.WriteMessage(xdr);
        xdr.Flush();
        Console.WriteLine("消息寫入成功");
  1. 使用WriteBodyContents寫入消息結構,寫入后我們可以看到log.xml的文件結構如下:

   

  2.  使用WriteBody寫入消息結構,寫入后我們可以看到log.xml的文件結構如下:

   

  3.  使用WriteMessage寫入消息結構,寫入后我們可以看到log.xml的文件結構如下

   

 

讀取消息

 

  • 讀取消息正文的主要方式是調用 GetReaderAtBodyContents。您會取回一個 XmlDictionaryReader 以便用於讀取消息正文。請注意,只要調用了 GetReaderAtBodyContents,Message 就會轉換到 Read 狀態,而不是在您使用返回的 XML 讀取器時發生轉換。
  • 使用 GetBody 方法還可以將消息正文作為類型化對象進行訪問。在內部,此方法使用 GetReaderAtBodyContents,因而也會將消息狀態轉換為 Read 狀態。
  • 接下來,我將使用GetBody來讀取從對象中創建的消息,參考代碼如下:
    //讀取消息
        Message message = proxy.GetDataObject();
        User user = message.GetBody<User>();
        Console.WriteLine("讀取消息信息成功");
        Console.WriteLine(user.ID+"->"+user.Name);

  運行結果顯示如下:

  

 

將消息復制到緩沖區中

 

  • 要使整個消息緩存到內存中,可以通過調用 CreateBufferedCopy 達到此目的。此方法采用一個表示最大緩沖區大小的整型參數,且創建一個不大於此大小的緩沖區。
  • 緩沖區作為一個 MessageBuffer 實例返回。可以通過幾種方式訪問緩沖區中的數據。主要方式是調用 CreateMessage 以便從緩沖區創建 Message 實例。
  • 訪問消息緩沖區內容的方式是使用 WriteMessage 將緩沖區的內容寫出到流中。
  • 接下來,我們通過使用CreateBufferedCopy來創建消息緩存區,並使用WriteMessage將消息寫入到log.xml文件中,參考代碼如下:
       //復制消息
        Message message = proxy.GetDataXml();
        MessageBuffer mb = message.CreateBufferedCopy(65536);
        FileStream stream = new FileStream(@"c:/log.xml", FileMode.Create);
        mb.WriteMessage(stream);
        stream.Flush();
        Console.WriteLine("復制消息信息成功");

  運行后,log.xml文件結構如下:

  

 

訪問其他消息部分

 

  • Headers 屬性表示消息頭。可以通過類型為 MessageHeaders 的 Headers 屬性來訪問標頭。MessageHeaders 是一個 MessageHeaderInfo 對象集合,可以通過其 IEnumerable 接口或其索引器來訪問各個標頭。
  • Properties 屬性表示消息屬性,這些屬性是附加到消息的命名數據段,且通常不會在發送消息時發出。請參見本主題稍后關於“使用屬性”的部分。
  • Version 屬性指示與消息相關聯的 SOAP 和 WS-Addressing 版本;如果禁用了 SOAP,則該屬性為 None。
  • IsFault 屬性在消息為 SOAP 錯誤消息時返回 true。
  • IsEmpty 屬性在消息為空時返回 true。
  • 接下來,我們將通過Message的實例輸出其屬性,參考代碼如下:
          //訪問消息的其他部分
          Message message = proxy.GetDataEmpty();
          Console.WriteLine("Version:" + message.Version.ToString());
          Console.WriteLine("State:" + message.State.ToString());
          Console.WriteLine("IsEmpty:" + message.IsEmpty.ToString());
          Console.WriteLine("IsFault:" + message.IsFault.ToString());
          Console.WriteLine("消息Headers包含的屬性如下:");
          foreach (MessageHeaderInfo item in message.Headers)
          {
              Console.WriteLine(item.Name);
          }

  運行結果如下:

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM