Welcome

首页 / 软件开发 / WCF / WCF技术剖析之十七:消息(Message)详解(中篇)

WCF技术剖析之十七:消息(Message)详解(中篇)2012-11-05 博客园 Artech在上篇中大体上围绕着Message的两个话题进行讲述:消息版本(Message Version)和采用五种不同的方式创建Message。本篇文章将会详细介绍Message的另外两个主题:和消息的基本操作,比如读、写、拷贝、关闭等,以及消息状态机(Message State Machine)。

知道了消息是如何创建的,我们接着讨论消息的一些基本的操作。除了上面介绍的消息创建之外,一个消息涉及到的操作大体分为以下4类:

读消息:读取整个消息的内容或者有选择地读取报头或者主体部分内容;

写消息:将整个消息的内容或者主体部分内容写入文件或者流;

拷贝消息:通过消息拷贝生成另一个具有相同内容的新消息;

关闭消息:关闭消息,回收一些非托管资源。

上述的这些消息的基本操作都和消息的状态密切相关,消息操作和消息状态之间的关系体现在以下两个方面:

消息的状态决定了可以采取的操作;

消息操作伴随着消息状态的改变。

一、消息状态机(Message State Machine)

图1展示的是基于消息的状态机,从图中我们可以得出下面的一些关于Message对象状态转换的规则:

消息的读、写和拷贝操作只能作用于状态为Created的消息上;

消息的读、写和拷贝将消息状态从Created转换成Read、Written和Copied。

所有状态的消息都可以直接关闭,关闭后消息的状态转换为Closed。

图1 Message对象状态机

在WCF中,消息的状态通过System.ServiceModel.Channels.MessageState枚举表示,MessageState定义了5种消息状态,与上图所示的5种状态一一对应。MessageState的定义如下:

 1: public enum MessageState
2: {
3: Created,
4: Read,
5: Written,
6: Copied,
7: Closed
8: }
二、消息的读取

读取消息主体部分的内容是最为常见的操作。如果主体部分的内容对应一个可以序列化的对象,可以通过GetBody<T>方法读取消息主体并反序列化生成相应的对象。而通过GetReaderAtBodyContents得到一个XmlDictionaryReader对象,通过这个对象可以进一步提取消息主体部分的内容。

 1: public abstract class Message : IDisposable
2: {
3: //其他成员
4: public T GetBody<T>();
5: public T GetBody<T>(XmlObjectSerializer serializer);
6: public XmlDictionaryReader GetReaderAtBodyContents();
7: }
我们演示一下GetBody<T>方法的例子。假设消息主体部分对应的类型为下面所示的Customer类,这是一个数据契约。

 1: [DataContract(Namespace = "http://www.artech.com")]
2: public class Customer
3: {
4: [DataMember]
5: public string Name
6: { get; set; }
7:
8: [DataMember]
9: public string Compnay
10: { get; set; }
11:
12: [DataMember]
13: public string Address
14: { get; set; }
15:
16: public override bool Equals(object obj)
17: {
18: Customer customer = obj as Customer;
19: if (customer == null)
20: {
21: return false;
22: }
23: return this.Name == customer.Name && this.Compnay == customer.Compnay && this.Address == customer.Address;
24: }
25: }