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

  运行结果如下:

  

时间: 2024-12-06 07:17:41

WCF初探-23:WCF中使用Message类(下)的相关文章

WCF初探-22:WCF中使用Message类(上)

前言 从我们学习WCF以来,就一直强调WCF是基于消息的通信机制.但是由于WCF给我们做了高级封装,以至于我们在使用WCF的时候很少了解到消息的内部机制.由于WCF的架构的可扩展性,针对一些特殊情况,WCF为我们提供了Message类来深度定制消息结构,以便我们拓展WCF的通信机制. 在之前的文章中,我们针对一些常用的WCF传递数据的方式进行了说明,比如数据协定和消息协定等.他们传递的数据最终都会转化为消息的实例.具体参照:        WCF初探-16:WCF数据协定之基础知识       

WCF初探-25:WCF中使用XmlSerializer类

前言 在上一篇WCF序列化和反序列化中,文章介绍了WCF序列化和反序列化的机制,虽然WCF针对序列化提供了默认的DataContractSerializer序列化引擎,但是WCF还支持其他的序列化引擎,那就是XmlSerializer序列化引擎.本文将详细介绍XmlSerializer类在WCF中具体的使用方式. XmlSerializer类概述 XmlSerializer 类不是 WCF 的专用类.ASP.NET Web 服务同样使用该类作为序列化引擎. XmlSerializer 类支持的类

WCF初探-28:WCF中的并发

理解WCF中的并发机制 在对WCF并发机制进行理解时,必须对WCF初探-27:WCF中的实例化进行理解,因为WCF中的并发特点是伴随着服务实例上下文实现的.WCF的实例上下文模型可以通过InstanceContext的属性来进行设置,WCF中的并发就是指一个实例上下文处理请求消息的能力,当需要在一个实例上下文中处理多个消息请求时就会产生并发.所以当InstanceContextMode的值为PerSession或Single的时候就会产生并发的情况,这时我们可以通过设置ConcurrencyMo

WCF初探-27:WCF中的实例化

理解WCF中的实例化机制 “实例化”是指对用户定义的服务对象以及与其相关的 InstanceContext 对象的生存期的控制.也就是说我们的客户端程序在调用服务端方法时,需要实例化一个服务端代理类对象,实例化就是对这个对象的生命周期的管理(比如:代理服务对象的创建,对象调用服务端方法后需要对其进行的回收处理). 实例化行为(使用 System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode 属性进行设置)控制如何创建 Inst

WCF初探-26:WCF中的会话

理解WCF中的会话机制 在WCF应用程序中,会话将一组消息相互关联,从而形成对话.会话”是在两个终结点之间发送的所有消息的一种相互关系.当某个服务协定指定它需要会话时,该协定会指定所有调用(即,支持调用的基础消息交换)必须是同一对话的一部分.如果某个协定指定它允许使用会话但不要求使用会话,则客户端可以进行连接,并选择建立会话或不建立会话.如果会话结束,然后在同一个通道上发送消息,将会引发异常. WCF中的会话机制通过设置服务协定(ServiceContract)上的SessionMode的枚举值

从零开始学WCF(七)Message类

Message类是WCF的基本类 客户端与服务之间的所有通信最终都会产生要进行发送和接收的Message实例 通常不会与Message类直接进行交互.相反,您需要使用WCF服务模型构造(如数据协定,消息协定和操作协定)来描述传入消息和传出消息. 在以下情况下可能需要使用Message类 需要一种替代方式来创建传出的消息内容(例如,从磁盘上的文件直接创建消息),而不是序列化.net framework对象. 需要一种替代方式来使传入的消息内容(例如,需要将XSLT转换应用于原始XML内容),而不是

WCF基础之Message类

客户端和服务端的通信都是通过接收和发送的Message实例建立起来的,大多数情况我们通过服务协定.数据协定和消息协定来构造传入和传出消息的. 一般什么时候使用Message类呢?不需要将消息序列化或者反序列化为.NET对象,无论消息内容如何,都进行常规处理.比如:读取磁盘中的文件并作为消息发送等等. 操作协定中的Message类的使用和消息协定相似,都只能有至多一个参数,而且必须为Message类或者消息协定,返回值必须是void.Message类或者消息协定. 创建消息有很多种,其重载如下:

WCF初探-15:WCF操作协定

前言: 在前面的文章中,我们定义服务协定时,在它的操作方法上都会加上OperationContract特性,此特性属于OperationContractAttribute 类,将OperationContract应用于方法,以指示该方法实现作为服务协定(由 ServiceContractAttribute 属性指定)一部分的服务操作.OperationContractAttribute 属性声明方法是服务协定中的操作. 只有具有 OperationContractAttribute 属性的方法可

WCF初探-2:手动实现WCF程序

1.前言 上一篇,我们通过VS自带的模板引擎自动生成了一个wcf程序,接下来我们将手动实现一个wcf程序.由于应用程序开发中一般都会涉及到大量的增删改查业务,所以这个程序将简单演示如何在wcf中构建简单的增删改查服务.我们知道WCF是一组通讯服务框架,我将解决方案按大范围划分为服务端,客户端通过服务寄宿程序产生的代理来调用服务端的公开给客户端消费的方法.总个解决方案由五个项目工程: Service:定义服务契约接口和实现服务契约,此项目类型为类库项目 Common:通用层定义数据访问的帮助类,此