客户端和服务端的通信都是通过接收和发送的Message实例建立起来的,大多数情况我们通过服务协定、数据协定和消息协定来构造传入和传出消息的。
一般什么时候使用Message类呢?不需要将消息序列化或者反序列化为.NET对象,无论消息内容如何,都进行常规处理。比如:读取磁盘中的文件并作为消息发送等等。
操作协定中的Message类的使用和消息协定相似,都只能有至多一个参数,而且必须为Message类或者消息协定,返回值必须是void、Message类或者消息协定。
创建消息有很多种,其重载如下:
练习几个常用的重载:
从object创建消息,如下,中间的string类型的action参数其实是操作契约的ReplyAction。不过不知道为什么,object类型为消息协议时,客户端解析时总是报命名空间不对,我试过改wrappernamespace等等,都没用,是我用法有错么?有大神经过,请留言指教。
public Message GetData() { MessageModel model = }; MessageVersion ver = OperationContext.Current.IncomingMessageVersion; return Message.CreateMessage(ver, "www.waha.com/ICreateMessageServcie/GetDataResponse", model); }
在客户端获取方法如下(object对象只有在服务契约中才会生成在客户端,所以我是手动添加的,不知有没有其他方法,请留言!):
CreateMessageServcieClient myClient = new CreateMessageServcieClient(); var response = myClient.GetData(); var model = response.GetBody<MessageModel>(); Console.WriteLine("Name:{0} Age:{1}", model.Name, model.Age); Console.Read();
从xml读取器创建消息,如下:
public Message GetData() { FileStream stream = new FileStream(@"D:\Test.xml",FileModel.Open); XmlDictionaryReader xdr = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas()); MessageVersion ver = OperationContext.Currt.IncomingMessageVersion; return Message.CreateMessage(ver,"www.waha.com/ICreateMessageServcie/GetDataResponse",xdr); }
读取有两种如下:
Message msg = client.GetData(); FileStream stream = new FileStream(@"D:\Log.xml", FileMode.Create); XmlDictionaryWriter xdw = XmlDictionaryWriter.CreateTextWriter(stream); msg.WriteMessage(xdw); xdw.Flush();
Message msg = client.GetDataStream(); MessageBuffer mb = msg.CreateBufferedCopy(); FileStream stream = new FileStream(@"D:\Log.xml", FileMode.Append); mb.WriteMessage(stream); stream.Flush();
ok,顺带说了提取消息正文的三类方法:
将消息正文全部提出写入到xml文档中叫写入消息。
通过xml读取器根据需要逐个访问消息正文叫读取消息。
将整个消息复制到MessageBuffer的内存缓冲区中叫复制消息。
创建错误消息,如下:
public Message GetDataFault() { FaultCode fc = new FaultCode("Receiver"); MessageVersion ver = OperationContext.Current.IncomingMessageVersion; return Message.CreateMessage(ver, fc, "BadData", "www.waha.com/ICreateMessageServcie/GetDataResponse"); }
注意的是FaultCode不能被序列化,在客户端获取到的是xml。
当然还能访问消息的其他部分,获得消息的实例后直接点,就能看到,就不一直重复了。