• [MSDN]WCF(8)Message类


    说明:本内容来自微软的webcast,讲师为徐长龙。为了用手机阅读方便点,抄录存为txt。

    本次课程内容包括
    - Message 类概述
    - 使用 Message 类创建消息
    - 读取 Message 类消息

    Message 类概述
    - Message 类是 WCF 的基本类
    - 客户端与服务之间的所有通讯最终都会产生要进行发送和接收的 Message 实例。
    - 通常不会与 Message 类直接进行交互。相反,您需要使用 WCF 服务模型构造(如数据协定、消息协定和操作协定)来描述传入消息和传出消息。
    - 在以下情况下可能需要使用 Message 类
      - 需要一种替代方式来创建传出的消息内容(例如,从磁盘上的文件直接创建消息),而不是序列化.NET Framework 对象。
      - 需要一种替代方式来使用传入的消息内容(例如,需要将 XSLT 转换应用于原始 XML 内容),而不是反序列化为.NET Framework 对象。
      - 无论消息内容怎样都需要使用常规方式来处理消息(例如,在生成路由器、负载平衡器或发布-订阅系统时对消息进行路由或转发)。


    在操作中使用 Message 类
    - 可以将 Message 类用作操作的输入参数和/或操作的返回值。只要在操作中的任何位置使用了 Message,就必须遵从以下限制:
      - 操作不能具有任何 out 或 ref 参数。
      - 不能有一个以上的 input 参数。如果该参数存在,其类型必须为 Message 或消息协定。
      - 返回类型必须为void、Message 或消息协定类型
      [ServiceContract]
      public interface IMyService
      {
        [OperationContract]
        Message GetData();
        [OperationContract]
        void PutData(Message m);
      }


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


    从对象创建消息
    - 另一种重载采用一个附加的 Object 参数;此重载所创建的消息的正文是给定对象的序列化表示
      public Message GetData()
      {
        Person p = new Person();
        p.name="John Doe";
        p.age=42;
        MessageVersion ver = OperationContext.Current.IncomingMessageVersion;
        return Message.CreateMessage(ver,"GetDataResponse",p);
      }


    从 XML 读取器创建消息
    - 有些 CreateMessage 重载采用一个 XmlReader 或一个 XmlDicitionaryReader 而不是对象作为正文
      public Message GetData()
      {
        FileStream stream = new FileStream("myfile.xml",FileMode.Open);
        XmlDictionaryReader xdr = new XmlDictionaryReader.CreateTextReader(stream,new XmlDictionaryReaderQuotas());
        MessageVersion ver = OperationContext.Current.IncomingMessageVersion;
        return Message.CreateMessage(ver,"GetDataResponse",xdr);
      }


    创建错误消息
    - 可以使用某些 CreateMessage 重载创建 SOAP 错误消息。其中一个最简单的重载采用一个用于描述错误的 MessageFault 对象作为参数
      public Message GetData()
      {
        FaultCode fc = new FaultCode("Receiver");
        MessageVersion ver = OperationContext.Current.IncomingMessageVersion;
        return Message.CreateMessage(ver,fc,"Bad data","GetDataResponse");
      }


    提取消息正文数据
    - Message 类支持多种从其正文提取信息的方式。它们可以分为以下几类:
      - 将整个消息正文一次性写出到 XML 编写器。这称为“写入消息”。
      - 将 XML 读取器放在消息正文上。这使您可以在以后根据需要逐段访问消息正文。这称为“读取消息”。
      - 可以将整个消息(包括他的正文)复制到类型为 MessageBuffer 的内存中缓存区。这称为“复制消息”。


    写入消息
    - WriteBodyContents 方法将给定 Message 实例的正文内容写出到给定 XML 编写器。
    - WriteBody 方法进行相同的操作,不同之处在于该方法将正文内容封装在适当的包装元素(如<soap:body>)中。
    - 最后,WriteMessage 写出整个消息,包括SOAP包装信封和标头。请记住,如果SOAP被禁用(Version 为 MessageVersion.None ),则所有这三个方法都进行相同的操作:仅仅写出消息正文内容。
      public void PutData(Message m)
      {
        FileStream stream = new FileStream("myfile.xml",FileMode,Create);
        XmlDictionaryWriter xdw = XmlDictionaryWriter.CreateTextWriter(stream);
        m.WriterBodyContents(xdw);
        xdw.Flush();
      }


    读取消息
    - 读取消息正文的主要方式是调用GetReaderAtBodyContents.
    - 使用 GetBody 方法还可以将消息正文作为类型化对象进行访问。
      public void PutData(Message m)
      {
        Persion p = m.GetBody<Person>();
        Console.WriteLine(p.name);
      }


    将消息复制到缓冲区中
    - 通过调用 CreateBufferedCopy 在内存中缓冲整个消息(包括正文)。
    - 缓冲区作为一个 MessageBuffer 实例返回。可以通过几种方式访问缓冲区的数据。主要方式是调用 CreateMessage 以便从缓冲区创建 Message 实例。
    - 访问消息缓冲区内容的另一种方式是是 WriteMessage 将缓冲区的内容写出流中
      [OperationContract]
      public void ForwardMessage(Message m)
      {
        //Compy the message to a buffer
        MessageBuffer mb = m.CreateBufferedCopy(65536);

        //Forward to multipel recipients
        foreach (IOutputChannel channel in forwardingAddresses)
        {
          Message copy = mb.CreateMessage();
          channel.Send(copy);
        }

        //Log to a file.
        FileStream stream = new FileStream("log.xml",FileMode.Append);
        mb.WriteMessage(stream);
        stream.Flush();
      }


    访问其他消息部分
    - 该类提供了各种属性,以便访问除正文内容之外的其他与消息有关的信息。但是,一旦关闭了消息,将无法调用这些属性:
      - Headers 属性表示消息标头。请参见本主题稍后关于“使用标头”的部分。
      - Properties 属性表示消息属性,这些属性是附加到消息的命名数据段,且通常不会在发送消息时发出。请参见本主题稍后关于“使用属性”的部分。
      - Version 属性指示与消息相关联的SOAP 和 WS-Addressing 版本;如果禁用了 SOAP,则该属性为 None。
      - IsFault 属性在消息为 SOAP 错误消息时返回true。
      - IsEmpty 属性在消息为空时返回 true。


    使用标头
    public class MyService6:IMyService
    {
      public void PutData(Message m)
      {
        foreach (MessageHeaderInfo mhi in m.Headers)
        {
          Console.WriteLine(mhi.Name);
        }
      }

      public Message GetData()
      {
        throw new NotImplmentedException();
      }
    }

  • 相关阅读:
    60个生僻成语汇总
    人民网 ***讲话
    组合排序
    工具
    网络之网络设备
    《TCP协议到TCP通讯各种异常现象和分析》的学习
    Console
    RTT学习之ulog
    RTT之MQTT学习笔记
    项目管理-禅道
  • 原文地址:https://www.cnblogs.com/htht66/p/2328853.html
Copyright © 2020-2023  润新知