菜菜从零学习WCF八(Message类)

前言

本次记录主要记录三个重要的内容:

  1. Message类概述
  2. 使用Message类创建消息
  3. 读取Message类消息

第一部分--Message类概述

Message类是WCF的基本类。客户端与服务之间的所有通信最终都会产生要进行发送和接收的Message实例,通常不会与Message里直接进行交互。相反,您需要使用WCF服务

模型构造(如数据协定、消息协定和操作协定)来描述传入消息和传出协定。在以下情况下可能需要使用Message类:

    需要一种替代方式来创建传出的消息内容(例如,从磁盘上的文件直接创建消息),而不是序列化.NET Framework对象。

    需要一种替代方式来使用传入的消息内容(例如,需要将XSLT转换应用于原始XML内容),而不是反序列化为.NET  Framework对象。

    无论消息内容怎样都需要使用常规方式来处理消息(例如,在生成路由器、负载平衡器或发布-订阅系统时对消息进行路由或转发)。

在操作中使用Message类

可以将Message类用作操作的输入参数或操作的返回值。只要在操作中的任何位置使用了Message,就必须遵从以下限制:

   操作不能具有任何out或ref参数。

     如果该参数存在,其类型必须为Message或消息协定。

   返回类型必须为void、Message或消息协定类型

第二部分--创建简单消息

Message类提供了静态CreateMessage工厂方法,所有CreateMessage重载都采用一个类型为MessageVersion的版本参数,该参数指示要用于消息的SOAP和WS-Addressing版本。如果要使用与传入消息相同的协议版本,则可以使用OperaionContext实例(从Current属性获取)上的IncomingMessageVersion属性。大多数CreateMessage重载还具有一个字符串参数,该参数指示要用于消息的SOAP操作。可以将版本设置为None以禁用SOAP信封生成:消息将仅包含正文。

从对象创建消息

另一种重载采用一个附加的Object参数;此重载所创建的消息的正文是给定对象的序列化表示

        public Message GetData()
        {
            Person p = new Person();
            p.name = "wang";
            p.age = 20;
            MessageVersion ver = OperationContext.Current.IncomingMessageVersion;
            return Message.CreateMessage(ver, "http://Microsoft.ServiceModel.Samples/ICalculator/GetDataResponse", p);
        }

从XML读取器创建消息  

有些CreateMessage重载采用一个XmlReader或一个XmlDictionaryReader而不是对象作为正文

        public Message GetDataStream()
        {
            FileStream stream = new FileStream(@"C:\myfile.xml", FileMode.Open);
            XmlDictionaryReader xdr =
                   XmlDictionaryReader.CreateTextReader(stream,
                               new XmlDictionaryReaderQuotas());
            MessageVersion ver =
                OperationContext.Current.IncomingMessageVersion;
            return Message.CreateMessage(ver, "http://Microsoft.ServiceModel.Samples/ICalculator/GetDataStreamResponse", xdr);
        }

创建错误消息

可以使用某些CreateMessage重载创建SOAP错误消息。其中一个最简单的重载采用一个用于描述错误的MessageFault对象作为参数

        public Message GetDataFault()
        {
            FaultCode fc = new FaultCode("Receiver");
            MessageVersion ver = OperationContext.Current.IncomingMessageVersion;
            return Message.CreateMessage(ver, fc, "Bad data", "http://Microsoft.ServiceModel.Samples/ICalculator/GetDataFaultResponse");
        }

第三部分--读取Message类消息 

Message类支持多种从其正文提取消息的方式。他们可以分为以下几类:

  1. 将整个消息正文一次性写出到XML编写器。这称为“写入消息”。
  2. 将XML读取器放在消息正文上。这使您可以在以后根根据需要逐段访问消息正文。这称为“读取消息”。
  3. 可以将整个消息(包括它的正文)复制到类型为MessageBuffer的内存中缓冲区。这称为“复制消息”。

1.写入消息

WriteBodyContents 方法将给定Message实例的正文内容写出到给定XML编写器。

WriteBody写法进行相同的操作,不同之处在于该方法将正文内容封装在适当的包装元素中。

最后WriteMessage写出整个消息,包括SOAP包装信封和标头。请记住,如果SOAP被禁用(Version为MessageVersion.None),则所有这三个方法都进行相同的操作:仅仅写出消息正文内容。

                Message reply1 = client.GetDataStream();
                Console.WriteLine(reply1.ToString());
                FileStream stream = new FileStream(@"c:\log.xml", FileMode.Create);
                XmlDictionaryWriter xdw =
                XmlDictionaryWriter.CreateTextWriter(stream);
                reply1.WriteBodyContents(xdw);
                reply1.WriteBody(xdw);
                reply1.WriteMessage(xdw);
                xdw.Flush();

2.读取消息  

读取消息正文的主要方式是调用GetReaderAtBodyContents.

使用GetBody方法还可以将消息振文作为类型化对象进行访问

                Message reply1 = client.GetData();
                Person p = reply1.GetBody<Person>();
                Console.WriteLine(p.name + "    " + p.age.ToString());

3.复制消息

通过调用CreateBufferedCopy在内存中缓冲整个消息(包括正文)

缓冲区作为一个MessageBuffer实例返回。可以通过几种方式访问缓冲区中的数据。主要方式是调用CreateMessage以便从缓冲区创建Message实例

访问消息缓冲区内容的另一种方式是使用WriteMessage将缓冲区的内容写出到流中

                Message reply1 = client.GetDataStream();
                //Copy the message to a buffer.
                MessageBuffer mb = reply1.CreateBufferedCopy(65536);

访问其他消息部分  

该类提供了各种属性,以便访问除曾文内容之外的其他与消息有关的信息。但是,一旦关闭了消息,将无法调用这些属性:

  Headers属性表示消息标头。

  Properties属性表示消息属性,这些属性是附加到消息的命名数据段,且通常不会在发送消息时发出。

  Version属性指示与消息相关联的SOAP和WS-Addressing版本;如果禁用了SOAP,则该属性为None.

  IsFault属性在消息为SOAP错误消息时返回true.

  IsEmpty属性在消息为空时返回true.

总结

 本次课程主要了解Message的概述,以及简单的使用Message类创建消息,以及读取Message类消息。

原文地址:https://www.cnblogs.com/aehyok/p/2964445.html