Message小结(一)

  一、消息版本

        为了区别消息的结构和寻址机制,W3C定制了SOAP1.1和SOAP1.2定义消息的结构,WS-Addressing 2004和WS-Addressing 1.0定义消息的寻址机制。

它们对应的命名空间如下:

       SOAP1.1:http://schemas.xmlsoap.org/soap/envelope/

       SOAP1.2:http://www.w3.org/2003/05/soap-envelope

       WS-Addressing 2004:http://schemas.xmlsoap.org/ws/2004/08/addressing

       WS-Addressing 1.0:http://www.w3.org/2005/08/addressing

Soap12WSAddressingAugust2004版本的消息:

<s:Envelope xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" 
xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://www.cnblogs.com/</a:Action>
  </s:Header>
  <s:Body>
    <Order xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication4">
      <Name>Order</Name>
      <Price>85</Price>
    </Order>
  </s:Body>
</s:Envelope>

 Soap11WSAddressing10版本消息:

<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://www.cnblogs.com/</a:Action>
  </s:Header>
  <s:Body>
    <Order xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication4">
      <Name>Order</Name>
      <Price>85</Price>
    </Order>
  </s:Body>
</s:Envelope>

   详情看MessageVersion类,可以通过CreateVersion(EnvelopeVersion envelopeVersion, AddressingVersion addressingVersion)创建对于的消息版本,以及已经定义好的Soap11WSAddressing10、Soap11WSAddressingAugust2004、Soap11、Soap12等消息版本。

二、创建消息

      先定义如下一个将消息写入指定文本的方法。writer.Formatting = Formatting.Indented;的作用是使文本Message缩进显示。

 public static void WriteMessage(Message msg, string path)
        {
            using (XmlTextWriter writer = new XmlTextWriter(path,Encoding.UTF8))
            {
                writer.Formatting = Formatting.Indented;
                msg.WriteMessage(writer);
            }
        }

 

      (1)创建空白消息

          Message的静态方法:public static Message CreateMessage(MessageVersion version, string action);

 static void Main(string[] args)
        {
            Message msg = Message.CreateMessage(MessageVersion.Soap12WSAddressingAugust2004, "http://www.cnblogs.com/");
            WriteMessage(msg, @"D:\1.txt");
        }

        空消息为:

<s:Envelope xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" 
xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://www.cnblogs.com/</a:Action>
  </s:Header>
  <s:Body />
</s:Envelope>

   (2)消息内容为可序列化的对象

    class Program
    {
        static void Main(string[] args)
        {
            Order order = new Order() { Name = "Order", Price = 88 };
Message msg = Message.CreateMessage(MessageVersion.Soap12, "http://www.cnblogs.com/", order); WriteMessage(msg, @"D:\1.txt"); } } [DataContract] public class Order { [DataMember] public string Name; [DataMember] public int Price; }

     1.txt中的消息为:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://www.cnblogs.com/</Action>
  </s:Header>
  <s:Body>
    <Order xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication4">
      <Name>Order</Name>
      <Price>85</Price>
    </Order>
  </s:Body>
</s:Envelope>

 

 (3)通过XmlReader将文件中的内容读取到消息中

 static void Main(string[] args)
        {
            Message msg = Message.CreateMessage(MessageVersion.Soap12, "http://www.cnblogs.com/", new XmlTextReader(@"D:\1.txt"));
            WriteMessage(msg, @"D:\2.txt");
        }

 

(4)通过XmlElement构造消息Body

static void Main(string[] args)
        {
            XNamespace ns = "msdn.microsoft.com";
            XElement Body = new XElement(new XElement(ns + "Order",
                new XElement(ns + "Name", "JDTmall"),
                new XElement(ns + "Price", "85")
                ));
            Message msg = Message.CreateMessage(MessageVersion.Soap12, "http://www.cnblogs.com/", Body);
            WriteMessage(msg, @"D:\1.txt");
        }

 1.txt中的消息为:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://www.cnblogs.com/</Action>
  </s:Header>
  <s:Body>
    <Order xmlns="msdn.microsoft.com">
      <Name>JDTmall</Name>
      <Price>85</Price>
    </Order>
  </s:Body>
</s:Envelope>

 

三、消息的状态

     指定消息的状态,消息只能被操作一次,从Created到Read、Written、Copied、Closed。操作过一次的消息后无法还原,即不可能再转变成Created状态。

public enum MessageState
    {
        //消息已创建。
        Created = 0,
        //消息正在被读取。
        Read = 1,
        //消息已写入。
        Written = 2,
        //消息已复制。
        Copied = 3,
        // 消息已关闭,无法再进行访问。
        Closed = 4,
    }

 (1)Created到Read

         如果消息Body是一个可序列化的对象,可以通过public T GetBody<T>();将Body内容反序列化为对象,也可以通过public T GetBody<T>(XmlObjectSerializer serializer);指定序列化器。

 static void Main(string[] args)
        {
            Order order = new Order() { Name = "Order", Price = 88 };
            Message msg = Message.CreateMessage(MessageVersion.Soap12, "http://www.cnblogs.com/", order);
            Console.WriteLine("MessageState :{0}", msg.State);
            Order o2 = msg.GetBody<Order>();
            Console.WriteLine("MessageState After Read :{0}", msg.State);
            Console.WriteLine("Message Body:{0} {1}", o2.Name, o2.Price);
        }

 

(2)Created到Written

WriteMessage函数内会调用public void WriteMessage(XmlWriter writer);方法。

static void Main(string[] args)
        {
            Order order = new Order() { Name = "Order", Price = 88 };
            Message msg = Message.CreateMessage(MessageVersion.Soap12, "http://www.cnblogs.com/", order);
            Console.WriteLine("MessageState :{0}", msg.State);
            WriteMessage(msg,@"D:\1.txt");
            Console.WriteLine("MessageState After Write :{0}", msg.State);
        }

 

(3)Created到Copied

public MessageBuffer CreateBufferedCopy(int maxBufferSize);

static void Main(string[] args)
        {
            Order order = new Order() { Name = "Order", Price = 88 };
            Message msg = Message.CreateMessage(MessageVersion.Soap12, "http://www.cnblogs.com/", order);
            Console.WriteLine("MessageState :{0}", msg.State);
            MessageBuffer buffer = msg.CreateBufferedCopy(int.MaxValue);
            Console.WriteLine("MessageState After Copy :{0}", msg.State);
            Message msgClone = buffer.CreateMessage();
            Console.WriteLine("MessageState After Createbybuffer :{0}", msgClone.State);
        }

 可以将Message变为MessageBuffer,随后Message变为Copied状态。通过MessageBuffer可以无限次的复制消息。

 

posted @ 2015-05-19 00:17  lh_cn  阅读(1843)  评论(0编辑  收藏  举报