使用消息头
正如你在第二章里看到的一样,消息头块被SOAP消息基础结构用来表示地址 、路由和安全信息。因为WCF也是一个完全支持SOAP的消息处理基础结构,它包 含一些创建、序列化和分析SOAP消息头块的工具。记住Message类型是一个 SOAP 消息的CLR抽象,它定义的成员允许WCF基础结构使用发送或接受到的消息头块。 Message 类型的Headers属性提供了这个功能。和WCF里其它关键的类型一样,使 用Headers属性需要我在WCF API里与其它类型交互,即MessageHeader、 MessageHeaders和EndpointAddress 类型。这些类型的名字已经暗示了他们的作 用。例如,MessageHeader是对SOAP消息头块的泛型CLR抽象;MessageHeaders, 广义上说,是一组MessageHeader对象;EndpointAddress是对WS-Addressing endpoint规范的CLR抽象。具体使用的时候,这些类型提供了给Message插入、序 列化、编码、反序列化、解码消息头块,以及从反序列化的消息头块里提取信息 的能力。本节,我们将会研究这些基本类型,以及如何和Message一起使用。
MessageHeader类型
WCF里SOAP消息头的基本构建单位就是MessageHeader类型,它的对象模型和 Message 类型很像。与Message一样,MessageHeader是抽象类,它暴露了几个返 回MessageHeader子类型实例的工厂方法。 MessageHeader类型也定义了几个通 过XmlWriter或者XmlDictionaryWriter序列化MessageHeader内容的方法。
创建一个MessageHeader对象
MessageHeader类型上定义的几个CreateHeader工厂方法。每个工厂方法接受 一组参数,但是表示消息头块的name (String)、namespace (String)和 value (Object)的三个参数一直存在。其它参数允许我们自定义序列化器,还有其它 SOAP消息头块的属性如mustUnderstand、actor和relay。下面代码演示了如何创 建一个简单的带有WS-Addressing 规范里定义的MessageID 的MessageHeader对 象:
String WSAddNS = "http://www.w3.org/2005/08/addressing";
MessageHeader header = MessageHeader.CreateHeader ("MessageID",
WSAddNS, new UniqueId().ToString());
Console.WriteLine(header.ToString());
The following output is generated when this code executes:
运行结果如下:
<MessageID xmlns="http://www.w3.org/2005/08/addressing">
urn:uuid:
</MessageID>
注意到为了创建序列化为WS-Addressing MessageID (本例中使用String)消 息头块的MessageHeader 对象,必须知道XML namespace和MessageID的name。你 ,我是不知道,但是我是不愿意记住WS-*规范里的一对消息块name.WCF架构师也 有相同的感受,他们已经为我们提供了创建符合WS-*规范的消息头块的方式。本 书里我们会看到这几种方式,本章里的“MessageHeaders类型”一节就会讲到这 些内容。
这里要着重指出的是外貌可以构建表示自定义的消息头块的MessageHeader对 象,它不需要遵循WS-* 规范。例如,在消息发送到另一个消息参与者之前,订 单处理系统或许要增加一个名为PurchaseOrderInfo的消息头块到Message上。因 此,从前面的例子看出,我们可以简单地改变XML namespace、消息头块的name 和消息头块的值来满足程序的需求。
MessageHeader header = MessageHeader.CreateHeader ("PurchaseOrderDate",
"http://wintellect.com/POInfo", DateTime.Now);
Console.WriteLine(header.ToString());
This code generates the following output:
代码输出结果如下:
<PurchaseOrderDate xmlns="http://wintellect.com/POInfo">
2007-01-12T09:18:52.020824-04:00
</PurchaseOrderDate>
备注:正如你将在第九章里看到的,WCF基础结构可以使用消息契约为我们做 这些工作。当我们使用这种简单、不易出错的方法时,WCF基础结构会执行类似 前面的代码。同样要重点指出的是MessageHeader本身没什么价值,想赋予其任 何意义,我们需要在Message对象里引用这个对象。你会在本章后面的 “MessageHeaders类型“一节里详细学习这些内容。