zoukankan      html  css  js  c++  java
  • WCF初探23:WCF中使用Message类(下)

    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);
              }

      运行结果如下:

      

  • 相关阅读:
    2017校赛 问题 F: 懒人得多动脑
    2017校赛 C: 不爱学习的小W【模拟】
    方程解的个数【数论】
    小兔蹦蹦跳【脑洞】
    例2-2显示文字
    例2-6 数值转换列表
    例2-3 转换数值
    例2-1 输出文字
    例1-1 求n!
    #文件1向文件中输出字符数据——fgetc
  • 原文地址:https://www.cnblogs.com/grj001/p/12223780.html
Copyright © 2011-2022 走看看