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

简介: 前言 本次记录主要记录三个重要的内容: Message类概述 使用Message类创建消息 读取Message类消息 第一部分--Message类概述 Message类是WCF的基本类。

前言

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

  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类消息。

目录
相关文章
|
12月前
|
网络协议 网络架构 Windows
框架学习——WCF框架
框架学习——WCF框架
258 0
|
安全 网络协议 网络安全
WCF安全3-Transport与Message安全模式
WCF安全3-Transport与Message安全模式
113 0
WCF安全3-Transport与Message安全模式
|
安全 C#
WCF技术我们应该如何以正确的方式去学习掌握
一、WCF技术我该如何学习?       阿笨的回答是:作为初学者的我们,那么请跟着阿笨一起玩WCF吧,阿笨将带领大家如何以正确的姿势去掌握WCF技术。由于WCF技术知识点太多了,就纯基础概念性知识都可以单独出一本书来讲解,本次分享课程《C#面向服务编程技术WCF从入门到实战演练》开课之前,阿笨还是希望从没了解过WCF技术的童鞋们提前先了解一下WCF技术,至少要明白WCF技术的ABC三要素分别指的是什么。
1181 0
|
XML 网络架构 数据格式
|
机器学习/深度学习 消息中间件 开发框架
跟着Artech学习WCF(4) MSMQ 绑定
曾几何时 再看大家讨论各种构架时,经常出现在各个服务器间传递数据,经常出现MSMQ, 那是看到这个心理就郁闷,怎么整天折腾ASP.NET 就没遇见过这个东西 原来这个家伙藏在WCF里面 嘿嘿这次被我发现了 首先 第一次装IIS的话 默认是没有安装msmq 所以需要自己安装的   看Art...
797 0
|
存储
跟着Artech学习WCF(3) wcf 的状态问题
开始以为是wcf的session问题 敲了一边代码发现里面没有用session存储数据 经过 自己研究才发现作者是再将wcf的状态存储问题 项目结构如下   代码如下 using System; using System.
697 0
|
网络协议 安全 Windows
跟着Artech学习WCF(1)
折腾了老半天双向通信,不是端口绑定不上 就是创建代理失败要摸是 代理没有及时关闭Artech的代码看了半天无论是照抄还是改良都是不行,无奈到处看看test最后终于解决了 绑定协议现在只试了http还没有事tcp的 项目结构图如下   目前感觉客户端的调用部分代码很多不 来自博客园地址忘了呵呵     代码如下 using System; using System.
637 0